diff options
author | Jon Bratseth <bratseth@oath.com> | 2018-05-28 11:01:36 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@oath.com> | 2018-05-28 11:01:36 +0200 |
commit | 45779f7073a2832c411692af90432a29bd966083 (patch) | |
tree | 5bfbcf5e37c207444025f512bacdf70b7ccea4cb | |
parent | b299a201c4ffa1c22476f93a08288d1abb97f744 (diff) | |
parent | e7203cce8fa1092c501784cd50d3e559ff2f0020 (diff) |
Merge branch 'master' into bratseth/better-error-message
74 files changed, 703 insertions, 486 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java index e60aabd24e8..659a07cfd5c 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java @@ -60,7 +60,7 @@ public class DistributorCluster extends AbstractConfigProducer<Distributor> impl return s.toString(); } - private int getGCInterval(ModelElement documentNode) throws ParseException { + private int getGCInterval(ModelElement documentNode) { int gcInterval = 3600; if (documentNode != null) { gcInterval = documentNode.getIntegerAttribute("garbage-collection-interval", gcInterval); diff --git a/config/src/apps/vespa-get-config/getconfig.cpp b/config/src/apps/vespa-get-config/getconfig.cpp index 342b2b497bb..24e4623372e 100644 --- a/config/src/apps/vespa-get-config/getconfig.cpp +++ b/config/src/apps/vespa-get-config/getconfig.cpp @@ -164,7 +164,7 @@ GetConfig::Main() break; case 'h': retval = 0; - //@fallthrough@ + [[fallthrough]]; case '?': default: usage(); diff --git a/config/src/apps/vespa-ping-configproxy/pingproxy.cpp b/config/src/apps/vespa-ping-configproxy/pingproxy.cpp index 86b5a4a13ba..a88d7deb79a 100644 --- a/config/src/apps/vespa-ping-configproxy/pingproxy.cpp +++ b/config/src/apps/vespa-ping-configproxy/pingproxy.cpp @@ -99,7 +99,7 @@ PingProxy::Main() case '?': default: retval = 1; - // fallthrough + [[fallthrough]]; case 'h': usage(); return retval; diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java index e87d88c5ed0..2c46f2968ce 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java @@ -11,8 +11,6 @@ import java.time.Duration; public class ConfigServerMaintenance extends AbstractComponent { - private static final Duration intervalInCd = Duration.ofMinutes(5); - private final TenantsMaintainer tenantsMaintainer; private final ZooKeeperDataMaintainer zooKeeperDataMaintainer; @@ -20,12 +18,9 @@ public class ConfigServerMaintenance extends AbstractComponent { public ConfigServerMaintenance(ConfigserverConfig configserverConfig, ApplicationRepository applicationRepository, Curator curator) { - boolean isCd = configserverConfig.system().equals(SystemName.cd.name()); - Duration defaultInterval = isCd ? intervalInCd : Duration.ofMinutes(configserverConfig.maintainerIntervalMinutes()); - Duration tenantsMaintainerInterval = isCd ? intervalInCd : Duration.ofMinutes(configserverConfig.tenantsMaintainerIntervalMinutes()); - - tenantsMaintainer = new TenantsMaintainer(applicationRepository, curator, tenantsMaintainerInterval); - zooKeeperDataMaintainer = new ZooKeeperDataMaintainer(applicationRepository, curator, defaultInterval); + DefaultTimes defaults = new DefaultTimes(configserverConfig); + tenantsMaintainer = new TenantsMaintainer(applicationRepository, curator, defaults.tenantsMaintainerInterval); + zooKeeperDataMaintainer = new ZooKeeperDataMaintainer(applicationRepository, curator, defaults.zookeeperDataMaintainerInterval); } @Override @@ -34,4 +29,24 @@ public class ConfigServerMaintenance extends AbstractComponent { zooKeeperDataMaintainer.deconstruct(); } + /* + * Default values from config. If one of the values needs to be changed, add the value to + * configserver-config.xml in the config server application directory and restart the config server + */ + private static class DefaultTimes { + + private final Duration defaultInterval; + private final Duration tenantsMaintainerInterval; + private final Duration zookeeperDataMaintainerInterval; + + DefaultTimes(ConfigserverConfig configserverConfig) { + boolean isCd = configserverConfig.system().equals(SystemName.cd.name()); + + this.defaultInterval = Duration.ofMinutes(configserverConfig.maintainerIntervalMinutes()); + // TODO: Want job control or feature flag to control when to run this, for now use a very long interval unless in CD + this.tenantsMaintainerInterval = isCd ? defaultInterval : Duration.ofMinutes(configserverConfig.tenantsMaintainerIntervalMinutes()); + this.zookeeperDataMaintainerInterval = defaultInterval; + } + } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java b/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java index b899f690ee1..bdf395c1f0b 100644 --- a/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java +++ b/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java @@ -166,8 +166,8 @@ public class IndexFacts { } private Index getIndexFromDocumentTypes(String indexName, List<String> documentTypes) { - if (indexName==null || indexName.isEmpty()) - indexName="default"; + if (indexName == null || indexName.isEmpty()) + indexName = "default"; return getIndexByCanonicNameFromDocumentTypes(indexName, documentTypes); } @@ -191,6 +191,13 @@ public class IndexFacts { return Index.nullIndex; } + private Collection<Index> getIndexes(String documentType) { + if ( ! isInitialized()) return Collections.emptyList(); + SearchDefinition sd = searchDefinitions.get(documentType); + if (sd == null) return Collections.emptyList(); + return sd.indices().values(); + } + /** Calls resolveDocumentTypes(query.getModel().getSources(), query.getModel().getRestrict()) */ private Set<String> resolveDocumentTypes(Query query) { // Assumption: Search definition name equals document name. @@ -421,6 +428,11 @@ public class IndexFacts { return IndexFacts.this.getIndexFromDocumentTypes(indexName, Collections.singletonList(documentType)); } + /** Returns all the indexes of a given search definition */ + public Collection<Index> getIndexes(String documentType) { + return IndexFacts.this.getIndexes(documentType); + } + /** * Returns the canonical form of the index name (Which may be the same as * the input). diff --git a/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java b/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java index 644cacfa322..47becde7b19 100644 --- a/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java +++ b/container-search/src/main/java/com/yahoo/prelude/SearchDefinition.java @@ -83,7 +83,7 @@ public class SearchDefinition { } /** Returns the indices of this as a map */ - public Map<String,Index> indices() { + public Map<String, Index> indices() { return indices; } diff --git a/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java b/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java index e38c30c25ac..9d852c8822d 100644 --- a/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java +++ b/container-search/src/main/java/com/yahoo/prelude/logging/AccessLogEntry.java @@ -4,8 +4,10 @@ package com.yahoo.prelude.logging; /** * Hollow compatibility class for com.yahoo.container.logging.AccessLogEntry. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen + * @deprecated do not use */ +@Deprecated // TODO: Remove on Vespa 7 public class AccessLogEntry extends com.yahoo.container.logging.AccessLogEntry { public AccessLogEntry() { diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java index 5015ea063b4..e1b5842529f 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java @@ -2,6 +2,7 @@ package com.yahoo.prelude.query; +import com.google.common.annotations.Beta; import com.yahoo.protect.Validator; import java.util.Iterator; @@ -12,6 +13,7 @@ import java.util.Iterator; * The common path is the field name containing the struct. * @author baldersheim */ +@Beta public class SameElementItem extends CompositeIndexedItem { public SameElementItem(String commonPath) { diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/CollapsePhraseSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/CollapsePhraseSearcher.java index abf37c71b76..47e5651f64c 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/CollapsePhraseSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/CollapsePhraseSearcher.java @@ -15,9 +15,11 @@ import com.yahoo.search.searchchain.Execution; /** * Make single item phrases in query into single word items. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen */ public class CollapsePhraseSearcher extends Searcher { + + @Override public Result search(Query query, Execution execution) { QueryTree tree = query.getModel().getQueryTree(); Item root = tree.getRoot(); @@ -35,7 +37,6 @@ public class CollapsePhraseSearcher extends Searcher { return execution.search(query); } - private Item simplifyPhrases(Item root) { if (root == null) { return root; @@ -64,4 +65,5 @@ public class CollapsePhraseSearcher extends Searcher { else return root; } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java index 3d803b322ca..dd8f4eff666 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/IndexCombinatorSearcher.java @@ -22,14 +22,15 @@ import java.util.*; * Searcher to rewrite queries to achieve mixed recall between indices and * memory attributes. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen + * @deprecated do not use */ @After({PhaseNames.RAW_QUERY, PHRASE_REPLACEMENT}) @Before(PhaseNames.TRANSFORMED_QUERY) @Provides(IndexCombinatorSearcher.MIXED_RECALL_REWRITE) -// TODO: This is not necessary on Vespa 6, we should probably remove it from the default chain but keep it -// around until Vespa 6 to avoid breaking those who refer to it. +@Deprecated // TODO: Remove on Vespa 7 (not necessary any more) public class IndexCombinatorSearcher extends Searcher { + public static final String MIXED_RECALL_REWRITE = "MixedRecallRewrite"; private static class ArrayComparator implements Comparator<Attribute[]> { diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/NoRankingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/NoRankingSearcher.java index 72c38448936..7456f33d00f 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/NoRankingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/NoRankingSearcher.java @@ -1,16 +1,16 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.prelude.querytransform; - import java.util.List; import com.yahoo.component.chain.dependencies.After; import com.yahoo.component.chain.dependencies.Before; +import com.yahoo.search.Query; +import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.query.Sorting.FieldOrder; import com.yahoo.search.searchchain.Execution; - /** * Avoid doing relevance calculations if sorting only * on attributes. @@ -25,7 +25,7 @@ public class NoRankingSearcher extends Searcher { private static final String UNRANKED = "unranked"; @Override - public com.yahoo.search.Result search(com.yahoo.search.Query query, Execution execution) { + public Result search(Query query, Execution execution) { List<FieldOrder> s = (query.getRanking().getSorting() != null) ? query.getRanking().getSorting().fieldOrders() : null; if (s == null) { return execution.search(query); diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/NonPhrasingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/NonPhrasingSearcher.java index 7a548acbff7..ffb1b8a4965 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/NonPhrasingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/NonPhrasingSearcher.java @@ -5,6 +5,8 @@ import com.yahoo.component.ComponentId; import com.yahoo.component.chain.dependencies.After; import com.yahoo.component.chain.dependencies.Before; import com.yahoo.container.QrSearchersConfig; +import com.yahoo.search.Query; +import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.processing.request.CompoundName; import com.yahoo.search.searchchain.Execution; @@ -12,7 +14,7 @@ import com.yahoo.search.searchchain.Execution; import java.util.List; /** - * <p>Detects and removes certain phrases from the query.</p> + * Detects and removes certain phrases from the query. * * @author bratseth */ @@ -52,9 +54,9 @@ public class NonPhrasingSearcher extends Searcher { } @Override - public com.yahoo.search.Result search(com.yahoo.search.Query query, Execution execution) { - List<PhraseMatcher.Phrase> phrases=phraseMatcher.matchPhrases(query.getModel().getQueryTree().getRoot()); - if (phrases!=null && !query.properties().getBoolean(suggestonly, false)) { + public Result search(Query query, Execution execution) { + List<PhraseMatcher.Phrase> phrases = phraseMatcher.matchPhrases(query.getModel().getQueryTree().getRoot()); + if (phrases != null && !query.properties().getBoolean(suggestonly, false)) { remove(phrases); query.trace("Removing stop words",true,2); } @@ -64,9 +66,9 @@ public class NonPhrasingSearcher extends Searcher { private void remove(List<PhraseMatcher.Phrase> phrases) { // Removing the leaf replace phrases first to preserve // the start index of each replace phrase until removing - for (int i=phrases.size()-1; i>=0; i-- ) { - PhraseMatcher.Phrase phrase= phrases.get(i); - if (phrase.getLength()<phrase.getOwner().getItemCount()) // Don't removeField all + for (int i = phrases.size()-1; i >= 0; i-- ) { + PhraseMatcher.Phrase phrase = phrases.get(i); + if (phrase.getLength() < phrase.getOwner().getItemCount()) // Don't removeField all phrase.remove(); } } diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/NormalizingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/NormalizingSearcher.java index 02c8ecda60c..fdd6ad47a98 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/NormalizingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/NormalizingSearcher.java @@ -11,6 +11,7 @@ import com.yahoo.prelude.IndexFacts; import com.yahoo.prelude.IndexFacts.Session; import com.yahoo.prelude.query.*; import com.yahoo.prelude.query.WordAlternativesItem.Alternative; +import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.language.Language; import com.yahoo.language.Linguistics; @@ -46,7 +47,7 @@ public class NormalizingSearcher extends Searcher { } @Override - public com.yahoo.search.Result search(com.yahoo.search.Query query, Execution execution) { + public Result search(Query query, Execution execution) { normalize(query, execution.context().getIndexFacts().newSession(query)); return execution.search(query); } diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/PhraseMatcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/PhraseMatcher.java index f4891489216..e8e4dc39fd5 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/PhraseMatcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/PhraseMatcher.java @@ -20,15 +20,15 @@ public class PhraseMatcher { private FSA phraseFSA = null; - private boolean matchPhraseItems=false; + private boolean matchPhraseItems = false; - private boolean matchSingleItems=false; + private boolean matchSingleItems = false; /** Whether this should ignore regular plural/singular form differences when matching */ - private boolean ignorePluralForm=false; + private boolean ignorePluralForm = false; /** False to matche the longest phrase, true to match <i>all</i> phrases */ - private boolean matchAll =false; + private boolean matchAll = false; /** For null subclass only */ private PhraseMatcher() { diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/PhrasingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/PhrasingSearcher.java index d530ec6b45e..2f3f4dbd351 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/PhrasingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/PhrasingSearcher.java @@ -29,7 +29,7 @@ import java.util.List; @Provides(PhrasingSearcher.PHRASE_REPLACEMENT) public class PhrasingSearcher extends Searcher { - private static final CompoundName suggestonly=new CompoundName("suggestonly"); + private static final CompoundName suggestonly = new CompoundName("suggestonly"); public static final String PHRASE_REPLACEMENT = "PhraseReplacement"; diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/RecallSearcher.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/RecallSearcher.java index 4490d3c9b1e..69331a196a2 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/RecallSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/RecallSearcher.java @@ -38,7 +38,7 @@ public class RecallSearcher extends Searcher { private static final CompoundName recallName=new CompoundName("recall"); @Override - public com.yahoo.search.Result search(Query query, Execution execution) { + public Result search(Query query, Execution execution) { String recall = query.properties().getString(recallName); if (recall == null) return execution.search(query); diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java index 415ebd7871c..2f9e81c1607 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/DocumentSourceSearcher.java @@ -27,9 +27,12 @@ import java.util.Set; * will be returned when attribute prefetch filling is requested.</p> * * @author bratseth + * @deprecated use {@link com.yahoo.search.searchchain.testutil.DocumentSourceSearcher} */ @SuppressWarnings({"rawtypes"}) +@Deprecated // TODO: Remove on Vespa 7 public class DocumentSourceSearcher extends Searcher { + // as for the SuppressWarnings annotation above, we are inside // com.yahoo.prelude, this is old stuff, really no point firing off those // warnings here... @@ -38,7 +41,6 @@ public class DocumentSourceSearcher extends Searcher { private Map<Query, Result> completelyFilledResults = new HashMap<>(); private Map<Query, Result> attributeFilledResults = new HashMap<>(); private Map<Query, Result> unFilledResults = new HashMap<>(); - //private Result defaultUnfilledResult; /** Time (in ms) at which the index of this searcher was last modified */ long editionTimeStamp=0; @@ -101,11 +103,11 @@ public class DocumentSourceSearcher extends Searcher { } /** - * Returns a query clone which has offset and hits set to null. This is used by access to + * Returns a query clone which has source, offset and hits set to null. This is used by access to * the maps using the query as key to achieve lookup independent of offset/hits value */ - private com.yahoo.search.Query getQueryKeyClone(com.yahoo.search.Query query) { - com.yahoo.search.Query key=query.clone(); + private Query getQueryKeyClone(Query query) { + Query key = query.clone(); key.setWindow(0,0); key.getModel().setSources(""); return key; diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/FieldCollapsingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/FieldCollapsingSearcher.java index 71e54c810c2..21fa8962da4 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/FieldCollapsingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/FieldCollapsingSearcher.java @@ -19,10 +19,9 @@ import java.util.Map; /** - * A searcher which does parametrized collapsing. Based on - * SiteCollapsingSearcher. Deprecated - use grouping. + * A searcher which does parametrized collapsing. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen */ @SuppressWarnings("deprecation") @After(PhaseNames.RAW_QUERY) @@ -174,17 +173,18 @@ public class FieldCollapsingSearcher extends Searcher { } if (knownCollapses.containsKey(collapseId)) { - int numHitsThisField = knownCollapses.get(collapseId).intValue(); + int numHitsThisField = knownCollapses.get(collapseId); if (numHitsThisField < collapseSize) { result.hits().add(hit); ++numHitsThisField; - knownCollapses.put(collapseId, Integer.valueOf(numHitsThisField)); + knownCollapses.put(collapseId, numHitsThisField); } } else { - knownCollapses.put(collapseId, Integer.valueOf(1)); + knownCollapses.put(collapseId, 1); result.hits().add(hit); } } } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/JSONDebugSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/JSONDebugSearcher.java index c18f3d49da3..2330ca2382a 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/JSONDebugSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/JSONDebugSearcher.java @@ -16,16 +16,17 @@ import java.util.Iterator; /** * Save the query in the incoming state to a meta hit in the result. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen */ - public class JSONDebugSearcher extends Searcher { + public static final String JSON_FIELD = "JSON field: "; public static final String STRUCT_FIELD = "Structured data field (as json): "; public static final String FEATURE_FIELD = "Feature data field (as json): "; private static CompoundName PROPERTYNAME = new CompoundName("dumpjson"); + @Override public Result search(com.yahoo.search.Query query, Execution execution) { Result r = execution.search(query); String propertyName = query.properties().getString(PROPERTYNAME); @@ -53,4 +54,5 @@ public class JSONDebugSearcher extends Searcher { } return r; } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java index ca87c0c1d46..5c56379efc0 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/JuniperSearcher.java @@ -78,13 +78,13 @@ public class JuniperSearcher extends Searcher { @Override public void fill(Result result, String summaryClass, Execution execution) { Result workResult = result; - final int worstCase = workResult.getHitCount(); - final List<Hit> hits = new ArrayList<>(worstCase); - for (final Iterator<Hit> i = workResult.hits().deepIterator(); i.hasNext();) { - final Hit sniffHit = i.next(); + int worstCase = workResult.getHitCount(); + List<Hit> hits = new ArrayList<>(worstCase); + for (Iterator<Hit> i = workResult.hits().deepIterator(); i.hasNext();) { + Hit sniffHit = i.next(); if ( ! (sniffHit instanceof FastHit)) continue; - final FastHit hit = (FastHit) sniffHit; + FastHit hit = (FastHit) sniffHit; if (hit.isFilled(summaryClass)) continue; hits.add(hit); @@ -105,54 +105,46 @@ public class JuniperSearcher extends Searcher { Object searchDefinitionField = hit.getField(MAGIC_FIELD); if (searchDefinitionField == null) continue; - String searchDefinitionName = searchDefinitionField.toString(); - - // TODO: Switch to iterate over indexes in the outer loop: - //for (Index index : indexFacts.getIndexes(searchDefinitionName())) { - // if (index.getDynamicSummary() || index.getHighlightSummary()) { - // insertTags(hit.buildHitField(index.getName(), true, true), bolding, index.getDynamicSummary()); - // } - //} - for (String fieldName : hit.fields().keySet()) { - Index index = indexFacts.getIndex(fieldName, searchDefinitionName); - if (index.getDynamicSummary() || index.getHighlightSummary()) - insertTags(hit.buildHitField(fieldName, true, true), bolding, index.getDynamicSummary()); + + for (Index index : indexFacts.getIndexes(searchDefinitionField.toString())) { + if (index.getDynamicSummary() || index.getHighlightSummary()) { + HitField fieldValue = hit.buildHitField(index.getName(), true, true); + if (fieldValue != null) + insertTags(fieldValue, bolding, index.getDynamicSummary()); + } } } } - private void insertTags(final HitField oldProperty, final boolean bolding, final boolean dynteaser) { + private void insertTags(HitField oldProperty, boolean bolding, boolean dynteaser) { boolean insideHighlight = false; - for (final ListIterator<FieldPart> i = oldProperty.listIterator(); i.hasNext();) { - final FieldPart f = i.next(); - if (f instanceof SeparatorFieldPart) { + for (ListIterator<FieldPart> i = oldProperty.listIterator(); i.hasNext();) { + FieldPart f = i.next(); + if (f instanceof SeparatorFieldPart) setSeparatorString(bolding, (SeparatorFieldPart) f); - } - if (f.isFinal()) { - continue; - } + if (f.isFinal()) continue; - final String toQuote = f.getContent(); + String toQuote = f.getContent(); List<FieldPart> newFieldParts = null; int previous = 0; for (int j = 0; j < toQuote.length(); j++) { - final char key = toQuote.charAt(j); + char key = toQuote.charAt(j); switch (key) { - case RAW_HIGHLIGHT_CHAR: - newFieldParts = initFieldParts(newFieldParts); - addBolding(bolding, insideHighlight, f, toQuote, newFieldParts, previous, j); - previous = j + 1; - insideHighlight = !insideHighlight; - break; - case RAW_SEPARATOR_CHAR: - newFieldParts = initFieldParts(newFieldParts); - addSeparator(bolding, dynteaser, f, toQuote, newFieldParts, - previous, j); - previous = j + 1; - break; - default: - // no action - break; + case RAW_HIGHLIGHT_CHAR: + newFieldParts = initFieldParts(newFieldParts); + addBolding(bolding, insideHighlight, f, toQuote, newFieldParts, previous, j); + previous = j + 1; + insideHighlight = !insideHighlight; + break; + case RAW_SEPARATOR_CHAR: + newFieldParts = initFieldParts(newFieldParts); + addSeparator(bolding, dynteaser, f, toQuote, newFieldParts, + previous, j); + previous = j + 1; + break; + default: + // no action + break; } } if (previous > 0 && previous < toQuote.length()) { @@ -160,37 +152,30 @@ public class JuniperSearcher extends Searcher { } if (newFieldParts != null) { i.remove(); - for (final Iterator<FieldPart> j = newFieldParts.iterator(); j.hasNext();) { + for (Iterator<FieldPart> j = newFieldParts.iterator(); j.hasNext();) { i.add(j.next()); } } } } - private void setSeparatorString(final boolean bolding,final SeparatorFieldPart f) { - if (bolding) { + private void setSeparatorString(boolean bolding, SeparatorFieldPart f) { + if (bolding) f.setContent(separatorTag); - } else { + else f.setContent(ELLIPSIS); - } } - private void addSeparator(final boolean bolding, final boolean dynteaser, - final FieldPart f, final String toQuote, - final List<FieldPart> newFieldParts, final int previous, final int j) { - if (previous != j) { + private void addSeparator(boolean bolding, boolean dynteaser, FieldPart f, String toQuote, + List<FieldPart> newFieldParts, int previous, int j) { + if (previous != j) newFieldParts.add(new StringFieldPart(toQuote.substring(previous, j), f.isToken())); - } - if (dynteaser) { - final FieldPart s = (bolding ? new SeparatorFieldPart(separatorTag) : new SeparatorFieldPart(ELLIPSIS)); - newFieldParts.add(s); - } + if (dynteaser) + newFieldParts.add(bolding ? new SeparatorFieldPart(separatorTag) : new SeparatorFieldPart(ELLIPSIS)); } - private void addBolding(final boolean bolding, - final boolean insideHighlight, final FieldPart f, - final String toQuote, final List<FieldPart> newFieldParts, - final int previous, final int j) { + private void addBolding(boolean bolding, boolean insideHighlight, FieldPart f, String toQuote, + List<FieldPart> newFieldParts, int previous, int j) { if (previous != j) { newFieldParts.add(new StringFieldPart(toQuote.substring(previous, j), f.isToken())); } @@ -209,9 +194,8 @@ public class JuniperSearcher extends Searcher { } private List<FieldPart> initFieldParts(List<FieldPart> newFieldParts) { - if (newFieldParts == null) { + if (newFieldParts == null) newFieldParts = new ArrayList<>(); - } return newFieldParts; } diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/MultipleResultsSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/MultipleResultsSearcher.java index c47af9e32da..3b2fd596cfa 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/MultipleResultsSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/MultipleResultsSearcher.java @@ -17,7 +17,7 @@ import java.util.*; * * <p> For each group, the desired number of hits can be specified. </p> * - * @author tonytv + * @author tonytv */ public class MultipleResultsSearcher extends Searcher { diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/PosSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/PosSearcher.java index 33667349397..43717ecf6cd 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/PosSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/PosSearcher.java @@ -34,6 +34,7 @@ import com.yahoo.prelude.Location; @Before(PhaseNames.TRANSFORMED_QUERY) @Provides(PosSearcher.POSITION_PARSING) public class PosSearcher extends Searcher { + public static final String POSITION_PARSING = "PositionParsing"; private static final CompoundName posBb = new CompoundName("pos.bb"); @@ -52,7 +53,7 @@ public class PosSearcher extends Searcher { public final static double km2deg = 1000.000 * 180.0 / (Math.PI * 6356752.0); public final static double mi2deg = 1609.344 * 180.0 / (Math.PI * 6356752.0); - + @Override public Result search(Query query, Execution execution) { String bb = query.properties().getString(posBb); String ll = query.properties().getString(posLl); @@ -92,9 +93,8 @@ public class PosSearcher extends Searcher { } } catch (IllegalArgumentException e) { - // System.err.println("error: "+e); - return new Result(query, ErrorMessage.createInvalidQueryParameter( - "Error in pos parameters: " + Exceptions.toMessageString(e))); + return new Result(query, ErrorMessage.createInvalidQueryParameter("Error in pos parameters: " + + Exceptions.toMessageString(e))); } // and finally: query.getRanking().setLocation(loc); @@ -102,8 +102,8 @@ public class PosSearcher extends Searcher { } private void handleGeoCircle(Query query, String ll, Location target) { - double ewCoord = 0; - double nsCoord = 0; + double ewCoord; + double nsCoord; try { DegreesParser parsed = new DegreesParser(ll); ewCoord = parsed.longitude; @@ -111,9 +111,9 @@ public class PosSearcher extends Searcher { } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Unable to parse lat/long string '" +ll + "'", e); } - String radius = query.properties().getString(posRadius); - double radiusdegrees = 0.0; + String radius = query.properties().getString(posRadius); + double radiusdegrees; if (radius == null) { radiusdegrees = 50.0 * km2deg; } else if (radius.endsWith("km")) { @@ -133,8 +133,8 @@ public class PosSearcher extends Searcher { private void handleXyCircle(Query query, String xy, Location target) { - int xcoord = 0; - int ycoord = 0; + int xcoord; + int ycoord; // parse xy int semipos = xy.indexOf(';'); if (semipos > 0 && semipos < xy.length()) { @@ -143,8 +143,9 @@ public class PosSearcher extends Searcher { } else { throw new IllegalArgumentException("pos.xy must be in the format 'digits;digits' but was: '"+xy+"'"); } + String radius = query.properties().getString(posRadius); - int radiusUnits = 0; + int radiusUnits; if (radius == null) { radiusUnits = 5000; } else if (radius.endsWith("km")) { @@ -165,7 +166,6 @@ public class PosSearcher extends Searcher { target.setXyCircle(xcoord, ycoord, radiusUnits); } - private static void parseBoundingBox(String bb, Location target) { BoundingBoxParser parser = new BoundingBoxParser(bb); target.setBoundingBox(parser.n, parser.s, parser.e, parser.w); diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java index 81b948682df..32efcde6feb 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/QuerySnapshotSearcher.java @@ -11,19 +11,20 @@ import com.yahoo.search.searchchain.Execution; /** * Save the query in the incoming state to a meta hit in the result. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen + * @deprecated do not use */ - +@Deprecated // TODO: Remove on Vespa 7 public class QuerySnapshotSearcher extends Searcher { public Result search(Query query, Execution execution) { Query q = query.clone(); Result r = execution.search(query); - Hit h = new Hit("meta:querysnapshot", new Relevance( - Double.POSITIVE_INFINITY)); + Hit h = new Hit("meta:querysnapshot", new Relevance(Double.POSITIVE_INFINITY)); h.setMeta(true); h.setField("query", q); r.hits().add(h); return r; } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java index 4e604dcd226..558521a7a8d 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/QueryValidatingSearcher.java @@ -10,8 +10,10 @@ import com.yahoo.search.searchchain.Execution; /** * Ensures hits is 1000 or less and offset is 1000 or less. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen + * @deprecated do not use */ +@Deprecated // TODO: Remove on Vespa 7 public class QueryValidatingSearcher extends Searcher { public Result search(Query query, Execution execution) { diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java index d4cad7f1246..5dcc533fb1f 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java @@ -35,6 +35,7 @@ public class QuotingSearcher extends Searcher { } private static class QuoteTable { + private final int lowerUncachedBound; private final int upperUncachedBound; private final Map<Character, String> quoteMap; @@ -50,12 +51,10 @@ public class QuotingSearcher extends Searcher { boolean newIsEmpty = true; Map<Character, String> newQuoteMap = new HashMap<>(); for (Iterator<?> i = config.character().iterator(); i.hasNext(); ) { - QrQuotetableConfig.Character character - = (QrQuotetableConfig.Character)i.next(); + QrQuotetableConfig.Character character = (QrQuotetableConfig.Character)i.next(); if (character.ordinal() > 256) { newIsEmpty = false; - newQuoteMap.put(new Character((char)character.ordinal()), - character.quoting()); + newQuoteMap.put(new Character((char)character.ordinal()), character.quoting()); newUseMap = true; if (minOrd == 0 || character.ordinal() < minOrd) minOrd = character.ordinal(); @@ -64,8 +63,7 @@ public class QuotingSearcher extends Searcher { } else { newIsEmpty = false; - newLowerTable[character.ordinal()] - = character.quoting(); + newLowerTable[character.ordinal()] = character.quoting(); } } lowerUncachedBound = minOrd; @@ -75,22 +73,19 @@ public class QuotingSearcher extends Searcher { isEmpty = newIsEmpty; lowerTable = newLowerTable; } + public String get(char c) { - if (isEmpty) - return null; + if (isEmpty) return null; + int ord = (int)c; if (ord < 256) { return lowerTable[ord]; } else { - if ((!useMap) || ord < lowerUncachedBound - || ord > upperUncachedBound) - { + if ((!useMap) || ord < lowerUncachedBound || ord > upperUncachedBound) return null; - } - else { + else return quoteMap.get(new Character(c)); - } } } public boolean isEmpty() { @@ -107,35 +102,29 @@ public class QuotingSearcher extends Searcher { Result result = execution.search(query); execution.fill(result); QuoteTable translations = getQuoteTable(); - if (translations == null || translations.isEmpty()) { - return result; - } + if (translations == null || translations.isEmpty()) return result; + for (Iterator<Hit> i = result.hits().deepIterator(); i.hasNext(); ) { Hit h = i.next(); - if (h instanceof FastHit) { - quoteProperties((FastHit)h, translations); - } + if (h instanceof FastHit) + quoteFields((FastHit) h, translations); } return result; } - private void quoteProperties(FastHit hit, QuoteTable translations) { - for (Iterator<?> i = ((Set<?>) hit.fields().keySet()).iterator(); i.hasNext(); ) { - String propertyName = (String) i.next(); - Object entry = hit.getField(propertyName); - if (entry == null) { - continue; - } - Class<? extends Object> propertyType = entry.getClass(); - if (propertyType.equals(HitField.class)) { - quoteField((HitField) entry, translations); - } else if (propertyType.equals(String.class)) { - quoteProperty(hit, propertyName, (String)entry, translations); + private void quoteFields(FastHit hit, QuoteTable translations) { + hit.forEachField((fieldName, fieldValue) -> { + if (fieldValue != null) { + Class<?> fieldType = fieldValue.getClass(); + if (fieldType.equals(HitField.class)) + quoteField((HitField) fieldValue, translations); + else if (fieldType.equals(String.class)) + quoteField(hit, fieldName, (String) fieldValue, translations); } - } + }); } - private void quoteProperty(Hit hit, String fieldname, String toQuote, QuoteTable translations) { + private void quoteField(Hit hit, String fieldname, String toQuote, QuoteTable translations) { List<FieldPart> l = translate(toQuote, translations, true); if (l != null) { HitField hf = new HitField(fieldname, toQuote); @@ -144,13 +133,11 @@ public class QuotingSearcher extends Searcher { } } - private void quoteField(HitField field, QuoteTable translations) { for (ListIterator<FieldPart> i = field.listIterator(); i.hasNext(); ) { FieldPart f = i.next(); - if (!f.isFinal()) { - List<FieldPart> newFieldParts = translate(f.getContent(), translations, - f.isToken()); + if ( ! f.isFinal()) { + List<FieldPart> newFieldParts = translate(f.getContent(), translations, f.isToken()); if (newFieldParts != null) { i.remove(); for (Iterator<FieldPart> j = newFieldParts.iterator(); j.hasNext(); ) { @@ -161,33 +148,24 @@ public class QuotingSearcher extends Searcher { } } - private List<FieldPart> translate(String toQuote, QuoteTable translations, - boolean isToken) { + private List<FieldPart> translate(String toQuote, QuoteTable translations, boolean isToken) { List<FieldPart> newFieldParts = null; int lastIdx = 0; for (int i = 0; i < toQuote.length(); i++) { String quote = translations.get(toQuote.charAt(i)); if (quote != null) { - if (newFieldParts == null) { + if (newFieldParts == null) newFieldParts = new ArrayList<>(); - } - if (lastIdx != i) { - newFieldParts.add( - new StringFieldPart(toQuote.substring(lastIdx, i), - isToken)); - } + if (lastIdx != i) + newFieldParts.add(new StringFieldPart(toQuote.substring(lastIdx, i), isToken)); String initContent = Character.toString(toQuote.charAt(i)); - newFieldParts.add(new ImmutableFieldPart(initContent, - quote, - isToken)); + newFieldParts.add(new ImmutableFieldPart(initContent, quote, isToken)); lastIdx = i+1; } } - if (lastIdx > 0 && lastIdx < toQuote.length()) { - newFieldParts.add( - new StringFieldPart(toQuote.substring(lastIdx), - isToken)); - } + if (lastIdx > 0 && lastIdx < toQuote.length()) + newFieldParts.add(new StringFieldPart(toQuote.substring(lastIdx), isToken)); return newFieldParts; } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/ValidatePredicateSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/ValidatePredicateSearcher.java index 2e2c73b6707..9b6f5926b61 100644 --- a/container-search/src/main/java/com/yahoo/prelude/searcher/ValidatePredicateSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/searcher/ValidatePredicateSearcher.java @@ -20,7 +20,7 @@ import java.util.Collection; /** * Checks that predicate queries don't use values outside the defined upper/lower bounds. * - * @author <a href="mailto:magnarn@yahoo-inc.com">Magnar Nedland</a> + * @author Magnar Nedland */ @After(BooleanSearcher.PREDICATE) public class ValidatePredicateSearcher extends Searcher { @@ -78,4 +78,5 @@ public class ValidatePredicateSearcher extends Searcher { @Override public void onExit() {} } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java b/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java index 9de1a5e2a2d..bd61de7f783 100644 --- a/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java +++ b/container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java @@ -10,6 +10,7 @@ import com.yahoo.log.LogLevel; import com.yahoo.metrics.simple.MetricSettings; import com.yahoo.metrics.simple.MetricReceiver; import com.yahoo.processing.request.CompoundName; +import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.result.Coverage; @@ -207,7 +208,8 @@ public class StatisticsSearcher extends Searcher { * 2) Add response time to total response time (time from entry to return) * 3) ..... */ - public Result search(com.yahoo.search.Query query, Execution execution) { + @Override + public Result search(Query query, Execution execution) { if (query.properties().getBoolean(IGNORE_QUERY,false)) { return execution.search(query); } diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/Context.java b/container-search/src/main/java/com/yahoo/prelude/templates/Context.java index 7a904ea014c..7989f35e77b 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/Context.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/Context.java @@ -9,7 +9,10 @@ import com.yahoo.text.XML; * A set of variable bindings for template rendering * * @author bratseth + * @deprecated use a Renderer instead */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public abstract class Context { private boolean xmlEscape = true; diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java b/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java index f14d8ddf319..dab80580f61 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/FormattingOptions.java @@ -13,7 +13,10 @@ import java.util.Set; * Defines formatting options used with special kinds of hits. * * @author laboisse + * @deprecated use a Renderer instead */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public class FormattingOptions { public static final String DEFAULT_TYPE_ATTRIBUTE_NAME = "type"; diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java b/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java index 037d1a77d5c..4d1daa97306 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/HitContext.java @@ -17,7 +17,10 @@ import java.util.Set; * A context providing all the fields of a hit, and falls back to MapContext behavior for all other keys. * * @author tonytv + * @deprecated use a Renderer instead */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public class HitContext extends Context { private final Hit hit; diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java b/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java index 49c5ffa6e78..84d97b71f60 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/MapContext.java @@ -6,7 +6,12 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -/** A context having a map as secondary storage */ +/** + * A context having a map as secondary storage + * @deprecated use a Renderer instead + */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public class MapContext extends Context { private Map<String, Object> map = new LinkedHashMap<>(); diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java index a24fd623e4d..83118ec66ad 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/PageTemplateSet.java @@ -14,7 +14,10 @@ import java.io.Writer; * This is a variant of the tiled template set - see that class for details. * * @author bratseth + * @deprecated use a Renderer instead */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public class PageTemplateSet extends TiledTemplateSet { public PageTemplateSet() { diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java b/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java index 31e133d22d5..a639a6b97ec 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/SearchRendererAdaptor.java @@ -21,8 +21,10 @@ import java.util.Iterator; * Renders a search result using the old templates API. * * @author tonytv + * @deprecated do not use */ @SuppressWarnings({ "rawtypes", "deprecation", "unchecked" }) +@Deprecated // TODO: Remove on Vespa 7 public final class SearchRendererAdaptor extends Renderer { private final LogExceptionUserTemplateDelegator templates; diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/Template.java b/container-search/src/main/java/com/yahoo/prelude/templates/Template.java index 63bd3214b17..3d00be9d05b 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/Template.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/Template.java @@ -10,7 +10,10 @@ import java.io.Writer; * template mechanism by subclassing this. * * @author bratseth + * @deprecated use a Renderer instead */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public abstract class Template<T extends Writer> { /** @@ -19,8 +22,7 @@ public abstract class Template<T extends Writer> { * @param context the context to evaluate in * @param writer the writer to render to */ - public abstract void render(Context context,T writer) - throws java.io.IOException; + public abstract void render(Context context,T writer) throws java.io.IOException; /** diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java index 6bba0f620ee..91bc33e3e2a 100644 --- a/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java +++ b/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java @@ -70,7 +70,10 @@ import java.util.stream.Collectors; * * @author bratseth * @author laboisse + * @deprecated use a Renderer instead */ +@SuppressWarnings("deprecation") +@Deprecated // TODO: Remove on Vespa 7 public class TiledTemplateSet extends DefaultTemplateSet { private FormattingOptions hitOptionsForProvider; diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java index 1c6e92ebffc..e9e4e34727c 100644 --- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java +++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java @@ -230,7 +230,7 @@ public class SearchHandler extends LoggingRequestHandler { return (e.getCause() instanceof IllegalArgumentException) ? invalidParameterResponse(request, e) : illegalQueryResponse(request, e); - } catch (RuntimeException e) { // Make sure we generate a valid XML response even on unexpected errors + } catch (RuntimeException e) { // Make sure we generate a valid response even on unexpected errors log.log(Level.WARNING, "Failed handling " + request, e); return internalServerErrorResponse(request, e); } diff --git a/container-search/src/main/java/com/yahoo/search/querytransform/NGramSearcher.java b/container-search/src/main/java/com/yahoo/search/querytransform/NGramSearcher.java index 2768a546cd0..399ff6194c8 100644 --- a/container-search/src/main/java/com/yahoo/search/querytransform/NGramSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/querytransform/NGramSearcher.java @@ -40,8 +40,8 @@ public class NGramSearcher extends Searcher { private final CharacterClasses characterClasses; public NGramSearcher(Linguistics linguistics) { - gramSplitter= linguistics.getGramSplitter(); - characterClasses= linguistics.getCharacterClasses(); + gramSplitter = linguistics.getGramSplitter(); + characterClasses = linguistics.getCharacterClasses(); } @Override @@ -54,7 +54,7 @@ public class NGramSearcher extends Searcher { if (rewritten) query.trace("Rewritten to n-gram matching",true,2); - Result result=execution.search(query); + Result result = execution.search(query); recombineNGrams(result.hits().deepIterator(), session); return result; } @@ -160,10 +160,11 @@ public class NGramSearcher extends Searcher { if (hit.isMeta()) continue; Object sddocname = hit.getField(Hit.SDDOCNAME_FIELD); if (sddocname == null) return; - for (String fieldName : hit.fieldKeys()) { // TODO: Iterate over indexes instead - Index index = session.getIndex(fieldName, sddocname.toString()); + for (Index index : session.getIndexes(sddocname.toString())) { if (index.isNGram() && (index.getHighlightSummary() || index.getDynamicSummary())) { - hit.setField(fieldName, recombineNGramsField(hit.getField(fieldName), index.getGramSize())); + Object fieldValue = hit.getField(index.getName()); + if (fieldValue != null) + hit.setField(index.getName(), recombineNGramsField(fieldValue, index.getGramSize())); } } } diff --git a/container-search/src/main/java/com/yahoo/search/result/Templating.java b/container-search/src/main/java/com/yahoo/search/result/Templating.java index 47f40f3c7f5..9e191a1219c 100644 --- a/container-search/src/main/java/com/yahoo/search/result/Templating.java +++ b/container-search/src/main/java/com/yahoo/search/result/Templating.java @@ -15,8 +15,10 @@ import com.yahoo.search.query.Presentation; * Helper methods and data store for result attributes geared towards result * rendering and presentation. * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen + * @deprecated do not use */ +@Deprecated // TODO: Remove on Vespa 7 public class Templating { private final Result result; diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/testutil/DocumentSourceSearcher.java b/container-search/src/main/java/com/yahoo/search/searchchain/testutil/DocumentSourceSearcher.java index 56a6a702962..f4973ba4239 100644 --- a/container-search/src/main/java/com/yahoo/search/searchchain/testutil/DocumentSourceSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/searchchain/testutil/DocumentSourceSearcher.java @@ -28,7 +28,7 @@ import com.yahoo.search.searchchain.Execution; * Any field in the configured hits which has a name starting by attribute * will be returned when attribute prefetch filling is requested.</p> * - * @author bratseth + * @author bratseth */ public class DocumentSourceSearcher extends Searcher { @@ -85,7 +85,6 @@ public class DocumentSourceSearcher extends Searcher { private void addDefaultResults() { Query q = new Query("?query=default"); Result r = new Result(q); - // These four used to assign collapseId 1,2,3,4 - re-add that if needed r.hits().add(new Hit("http://default-1.html", 0)); r.hits().add(new Hit("http://default-2.html", 0)); r.hits().add(new Hit("http://default-3.html", 0)); @@ -97,8 +96,7 @@ public class DocumentSourceSearcher extends Searcher { @Override public Result search(Query query, Execution execution) { queryCount++; - Result r; - r = unFilledResults.get(getQueryKeyClone(query)); + Result r = unFilledResults.get(getQueryKeyClone(query)); if (r == null) { r = defaultFilledResult.clone(); } else { @@ -111,12 +109,13 @@ public class DocumentSourceSearcher extends Searcher { } /** - * Returns a query clone which has offset and hits set to null. This is used by access to + * Returns a query clone which has sourcr, offset and hits set to null. This is used by access to * the maps using the query as key to achieve lookup independent of offset/hits value */ private Query getQueryKeyClone(Query query) { - Query key=query.clone(); + Query key = query.clone(); key.setWindow(0,0); + key.getModel().setSources(""); return key; } diff --git a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java index 283a70c478b..4c5dfaabed7 100644 --- a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java +++ b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java @@ -30,6 +30,7 @@ import static com.yahoo.search.yql.YqlParser.PREFIX; import static com.yahoo.search.yql.YqlParser.RANGE; import static com.yahoo.search.yql.YqlParser.RANK; import static com.yahoo.search.yql.YqlParser.RANKED; +import static com.yahoo.search.yql.YqlParser.SAME_ELEMENT; import static com.yahoo.search.yql.YqlParser.SCORE_THRESHOLD; import static com.yahoo.search.yql.YqlParser.SIGNIFICANCE; import static com.yahoo.search.yql.YqlParser.STEM; @@ -79,6 +80,7 @@ import com.yahoo.prelude.query.PrefixItem; import com.yahoo.prelude.query.RangeItem; import com.yahoo.prelude.query.RankItem; import com.yahoo.prelude.query.RegExpItem; +import com.yahoo.prelude.query.SameElementItem; import com.yahoo.prelude.query.SegmentingRule; import com.yahoo.prelude.query.Substring; import com.yahoo.prelude.query.SubstringItem; @@ -106,8 +108,7 @@ public class VespaSerializer { // TODO refactor, too much copy/paste private static class AndSegmentSerializer extends Serializer { - private static void serializeWords(StringBuilder destination, - AndSegmentItem segment) { + private static void serializeWords(StringBuilder destination, AndSegmentItem segment) { for (int i = 0; i < segment.getItemCount(); ++i) { if (i > 0) { destination.append(", "); @@ -115,28 +116,23 @@ public class VespaSerializer { Item current = segment.getItem(i); if (current instanceof WordItem) { destination.append('"'); - escape(((WordItem) current).getIndexedString(), destination) - .append('"'); + escape(((WordItem) current).getIndexedString(), destination).append('"'); } else { - throw new IllegalArgumentException( - "Serializing of " - + current.getClass().getSimpleName() + throw new IllegalArgumentException("Serializing of " + current.getClass().getSimpleName() + " in segment AND expressions not implemented, please report this as a bug."); } } } @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { return serialize(destination, item, true); } - static boolean serialize(StringBuilder destination, Item item, - boolean includeField) { + static boolean serialize(StringBuilder destination, Item item, boolean includeField) { AndSegmentItem phrase = (AndSegmentItem) item; Substring origin = phrase.getOrigin(); String image; @@ -154,13 +150,11 @@ public class VespaSerializer { } if (includeField) { - destination.append(normalizeIndexName(phrase.getIndexName())) - .append(" contains "); + destination.append(normalizeIndexName(phrase.getIndexName())).append(" contains "); } destination.append("([{"); serializeOrigin(destination, image, offset, length); - destination.append(", \"").append(AND_SEGMENTING) - .append("\": true"); + destination.append(", \"").append(AND_SEGMENTING).append("\": true"); destination.append("}]"); destination.append(PHRASE).append('('); serializeWords(destination, phrase); @@ -189,13 +183,11 @@ public class VespaSerializer { private static class DotProductSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { - serializeWeightedSetContents(destination, DOT_PRODUCT, - (WeightedSetItem) item); + serializeWeightedSetContents(destination, DOT_PRODUCT, (WeightedSetItem) item); return false; } @@ -203,8 +195,7 @@ public class VespaSerializer { private static class EquivSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { @@ -240,8 +231,7 @@ public class VespaSerializer { private static class NearSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { @@ -304,8 +294,7 @@ public class VespaSerializer { private static class NullSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { @@ -319,31 +308,22 @@ public class VespaSerializer { private static class NumberSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { IntItem intItem = (IntItem) item; - if (intItem.getFromLimit().number() - .equals(intItem.getToLimit().number())) { - destination.append(normalizeIndexName(intItem.getIndexName())) - .append(" = "); - annotatedNumberImage(intItem, intItem.getFromLimit().number() - .toString(), destination); + if (intItem.getFromLimit().number().equals(intItem.getToLimit().number())) { + destination.append(normalizeIndexName(intItem.getIndexName())).append(" = "); + annotatedNumberImage(intItem, intItem.getFromLimit().number().toString(), destination); } else if (intItem.getFromLimit().isInfinite()) { destination.append(normalizeIndexName(intItem.getIndexName())); - destination.append(intItem.getToLimit().isInclusive() ? " <= " - : " < "); - annotatedNumberImage(intItem, intItem.getToLimit().number() - .toString(), destination); + destination.append(intItem.getToLimit().isInclusive() ? " <= " : " < "); + annotatedNumberImage(intItem, intItem.getToLimit().number().toString(), destination); } else if (intItem.getToLimit().isInfinite()) { destination.append(normalizeIndexName(intItem.getIndexName())); - destination - .append(intItem.getFromLimit().isInclusive() ? " >= " - : " > "); - annotatedNumberImage(intItem, intItem.getFromLimit().number() - .toString(), destination); + destination.append(intItem.getFromLimit().isInclusive() ? " >= " : " > "); + annotatedNumberImage(intItem, intItem.getFromLimit().number().toString(), destination); } else { serializeAsRange(destination, intItem); } @@ -358,21 +338,17 @@ public class VespaSerializer { int initLen; if (leftOpen && rightOpen) { - boundsAnnotation = "\"" + BOUNDS + "\": " + "\"" + BOUNDS_OPEN - + "\""; + boundsAnnotation = "\"" + BOUNDS + "\": " + "\"" + BOUNDS_OPEN + "\""; } else if (leftOpen) { - boundsAnnotation = "\"" + BOUNDS + "\": " + "\"" - + BOUNDS_LEFT_OPEN + "\""; + boundsAnnotation = "\"" + BOUNDS + "\": " + "\"" + BOUNDS_LEFT_OPEN + "\""; } else if (rightOpen) { - boundsAnnotation = "\"" + BOUNDS + "\": " + "\"" - + BOUNDS_RIGHT_OPEN + "\""; + boundsAnnotation = "\"" + BOUNDS + "\": " + "\"" + BOUNDS_RIGHT_OPEN + "\""; } if (annotations.length() > 0 || boundsAnnotation.length() > 0) { destination.append("[{"); } initLen = destination.length(); if (annotations.length() > 0) { - destination.append(annotations); } comma(destination, initLen); @@ -389,8 +365,7 @@ public class VespaSerializer { .append(")"); } - private void annotatedNumberImage(IntItem item, String rawNumber, - StringBuilder image) { + private void annotatedNumberImage(IntItem item, String rawNumber, StringBuilder image) { String annotations = leafAnnotations(item); if (annotations.length() > 0) { @@ -430,16 +405,14 @@ public class VespaSerializer { private static class RegExpSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { RegExpItem regexp = (RegExpItem) item; String annotations = leafAnnotations(regexp); - destination.append(normalizeIndexName(regexp.getIndexName())).append( - " matches "); + destination.append(normalizeIndexName(regexp.getIndexName())).append(" matches "); annotatedTerm(destination, regexp, annotations); return false; } @@ -498,8 +471,7 @@ public class VespaSerializer { private static class PhraseSegmentSerializer extends Serializer { - private static void serializeWords(StringBuilder destination, - PhraseSegmentItem segment) { + private static void serializeWords(StringBuilder destination, PhraseSegmentItem segment) { for (int i = 0; i < segment.getItemCount(); ++i) { if (i > 0) { destination.append(", "); @@ -507,20 +479,16 @@ public class VespaSerializer { Item current = segment.getItem(i); if (current instanceof WordItem) { destination.append('"'); - escape(((WordItem) current).getIndexedString(), destination) - .append('"'); + escape(((WordItem) current).getIndexedString(), destination).append('"'); } else { - throw new IllegalArgumentException( - "Serializing of " - + current.getClass().getSimpleName() - + " in phrases not implemented, please report this as a bug."); + throw new IllegalArgumentException("Serializing of " + current.getClass().getSimpleName() + + " in phrases not implemented, please report this as a bug."); } } } @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { @@ -535,8 +503,7 @@ public class VespaSerializer { int length; if (includeField) { - destination.append(normalizeIndexName(phrase.getIndexName())) - .append(" contains "); + destination.append(normalizeIndexName(phrase.getIndexName())).append(" contains "); } if (origin == null) { image = phrase.getRawWord(); @@ -555,8 +522,7 @@ public class VespaSerializer { destination.append(", ").append(annotations); } if (phrase.getSegmentingRule() == SegmentingRule.BOOLEAN_AND) { - destination.append(", ").append('"').append(AND_SEGMENTING) - .append("\": true"); + destination.append(", ").append('"').append(AND_SEGMENTING).append("\": true"); } destination.append("}]"); destination.append(PHRASE).append('('); @@ -568,16 +534,14 @@ public class VespaSerializer { private static class PhraseSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { return serialize(destination, item, true); } - static boolean serialize(StringBuilder destination, Item item, - boolean includeField) { + static boolean serialize(StringBuilder destination, Item item, boolean includeField) { PhraseItem phrase = (PhraseItem) item; String annotations = leafAnnotations(phrase); @@ -598,11 +562,9 @@ public class VespaSerializer { } Item current = phrase.getItem(i); if (current instanceof WordItem) { - WordSerializer.serializeWordWithoutIndex(destination, - current); + WordSerializer.serializeWordWithoutIndex(destination, current); } else if (current instanceof PhraseSegmentItem) { - PhraseSegmentSerializer.serialize(destination, current, - false); + PhraseSegmentSerializer.serialize(destination, current, false); } else if (current instanceof WordAlternativesItem) { WordAlternativesSerializer.serialize(destination, (WordAlternativesItem) current, false); } else { @@ -621,16 +583,60 @@ public class VespaSerializer { } - private static class PredicateQuerySerializer extends Serializer { + private static class SameElementSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { + void onExit(StringBuilder destination, Item item) { } + + @Override + boolean serialize(StringBuilder destination, Item item) { + return serialize(destination, item, true); } + static boolean serialize(StringBuilder destination, Item item, boolean includeField) { + + SameElementItem phrase = (SameElementItem) item; + String annotations = leafAnnotations(phrase); + + if (includeField) { + destination.append(normalizeIndexName(phrase.getIndexName())).append(" contains "); + + } + if (annotations.length() > 0) { + destination.append("([{").append(annotations).append("}]"); + } + + destination.append(SAME_ELEMENT).append('('); + for (int i = 0; i < phrase.getItemCount(); ++i) { + if (i > 0) { + destination.append(", "); + } + Item current = phrase.getItem(i); + if (current instanceof WordItem) { + new WordSerializer().serialize(destination, current); + + } else { + throw new IllegalArgumentException( + "Serializing of " + current.getClass().getSimpleName() + + " in same_element is not implemented, please report this as a bug."); + } + } + destination.append(')'); + if (annotations.length() > 0) { + destination.append(')'); + } + return false; + } + + } + + private static class PredicateQuerySerializer extends Serializer { + @Override + void onExit(StringBuilder destination, Item item) { } + @Override boolean serialize(StringBuilder destination, Item item) { PredicateQueryItem pItem = (PredicateQueryItem) item; - destination.append("predicate(").append(pItem.getIndexName()) - .append(','); + destination.append("predicate(").append(pItem.getIndexName()).append(','); appendFeatures(destination, pItem.getFeatures()); destination.append(','); appendFeatures(destination, pItem.getRangeFeatures()); @@ -638,8 +644,7 @@ public class VespaSerializer { return false; } - private void appendFeatures(StringBuilder destination, - Collection<? extends PredicateQueryItem.EntryBase> features) { + private void appendFeatures(StringBuilder destination, Collection<? extends PredicateQueryItem.EntryBase> features) { if (features.isEmpty()) { destination.append('0'); // Workaround for empty maps. return; @@ -651,8 +656,7 @@ public class VespaSerializer { destination.append(','); } if (entry.getSubQueryBitmap() != PredicateQueryItem.ALL_SUB_QUERIES) { - destination.append("\"0x").append( - Long.toHexString(entry.getSubQueryBitmap())); + destination.append("\"0x").append(Long.toHexString(entry.getSubQueryBitmap())); destination.append("\":{"); appendKeyValue(destination, entry); destination.append('}'); @@ -664,19 +668,16 @@ public class VespaSerializer { destination.append('}'); } - private void appendKeyValue(StringBuilder destination, - PredicateQueryItem.EntryBase entry) { + private void appendKeyValue(StringBuilder destination, PredicateQueryItem.EntryBase entry) { destination.append('"'); escape(entry.getKey(), destination); destination.append("\":"); if (entry instanceof PredicateQueryItem.Entry) { destination.append('"'); - escape(((PredicateQueryItem.Entry) entry).getValue(), - destination); + escape(((PredicateQueryItem.Entry) entry).getValue(), destination); destination.append('"'); } else { - destination.append(((PredicateQueryItem.RangeEntry) entry) - .getValue()); + destination.append(((PredicateQueryItem.RangeEntry) entry).getValue()); destination.append('L'); } } @@ -685,8 +686,7 @@ public class VespaSerializer { private static class RangeSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { @@ -737,8 +737,7 @@ public class VespaSerializer { private static class WordAlternativesSerializer extends Serializer { @Override - void onExit(StringBuilder destination, Item item) { - } + void onExit(StringBuilder destination, Item item) { } @Override boolean serialize(StringBuilder destination, Item item) { @@ -800,10 +799,8 @@ public class VespaSerializer { abstract void onExit(StringBuilder destination, Item item); String separator(Deque<SerializerWrapper> state) { - throw new UnsupportedOperationException( - "Having several items for this query operator serializer, " - + this.getClass().getSimpleName() - + ", not yet implemented."); + throw new UnsupportedOperationException("Having several items for this query operator serializer, " + + this.getClass().getSimpleName() + ", not yet implemented."); } abstract boolean serialize(StringBuilder destination, Item item); @@ -822,8 +819,7 @@ public class VespaSerializer { } - private static final class TokenComparator implements - Comparator<Entry<Object, Integer>> { + private static final class TokenComparator implements Comparator<Entry<Object, Integer>> { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override @@ -858,8 +854,7 @@ public class VespaSerializer { Serializer doIt = dispatch.get(item.getClass()); if (doIt == null) { - throw new IllegalArgumentException(item.getClass() - + " not supported for YQL+ marshalling."); + throw new IllegalArgumentException(item.getClass() + " not supported for YQL+ marshalling."); } if (state.peekFirst() != null && state.peekFirst().subItems > 0) { @@ -878,9 +873,7 @@ public class VespaSerializer { @Override boolean serialize(StringBuilder destination, Item item) { - serializeWeightedSetContents(destination, WAND, - (WeightedSetItem) item, - specificAnnotations((WandItem) item)); + serializeWeightedSetContents(destination, WAND, (WeightedSetItem) item, specificAnnotations((WandItem) item)); return false; } @@ -890,18 +883,15 @@ public class VespaSerializer { double scoreThreshold = w.getScoreThreshold(); double thresholdBoostFactor = w.getThresholdBoostFactor(); if (targetNumHits != 10) { - annotations.append('"').append(TARGET_NUM_HITS).append("\": ") - .append(targetNumHits); + annotations.append('"').append(TARGET_NUM_HITS).append("\": ").append(targetNumHits); } if (scoreThreshold != 0) { comma(annotations, 0); - annotations.append('"').append(SCORE_THRESHOLD).append("\": ") - .append(scoreThreshold); + annotations.append('"').append(SCORE_THRESHOLD).append("\": ").append(scoreThreshold); } if (thresholdBoostFactor != 1) { comma(annotations, 0); - annotations.append('"').append(THRESHOLD_BOOST_FACTOR) - .append("\": ").append(thresholdBoostFactor); + annotations.append('"').append(THRESHOLD_BOOST_FACTOR).append("\": ").append(thresholdBoostFactor); } return annotations.toString(); } @@ -963,8 +953,7 @@ public class VespaSerializer { @Override boolean serialize(StringBuilder destination, Item item) { - serializeWeightedSetContents(destination, WEIGHTED_SET, - (WeightedSetItem) item); + serializeWeightedSetContents(destination, WEIGHTED_SET, (WeightedSetItem) item); return false; } @@ -981,14 +970,12 @@ public class VespaSerializer { WordItem w = (WordItem) item; StringBuilder wordAnnotations = getAllAnnotations(w); - destination.append(normalizeIndexName(w.getIndexName())).append( - " contains "); + destination.append(normalizeIndexName(w.getIndexName())).append(" contains "); VespaSerializer.annotatedTerm(destination, w, wordAnnotations.toString()); return false; } - static void serializeWordWithoutIndex(StringBuilder destination, - Item item) { + static void serializeWordWithoutIndex(StringBuilder destination, Item item) { WordItem w = (WordItem) item; StringBuilder wordAnnotations = getAllAnnotations(w); @@ -996,8 +983,7 @@ public class VespaSerializer { } private static StringBuilder getAllAnnotations(WordItem w) { - StringBuilder wordAnnotations = new StringBuilder( - WordSerializer.wordAnnotations(w)); + StringBuilder wordAnnotations = new StringBuilder(WordSerializer.wordAnnotations(w)); String leafAnnotations = leafAnnotations(w); if (leafAnnotations.length() > 0) { @@ -1034,15 +1020,12 @@ public class VespaSerializer { length = origin.end - origin.start; } - if (!image.substring(offset, offset + length).equals( - item.getIndexedString())) { - VespaSerializer.serializeOrigin(annotation, image, offset, - length); + if (!image.substring(offset, offset + length).equals(item.getIndexedString())) { + VespaSerializer.serializeOrigin(annotation, image, offset, length); } if (usePositionData != true) { VespaSerializer.comma(annotation, initLen); - annotation.append('"').append(USE_POSITION_DATA) - .append("\": false"); + annotation.append('"').append(USE_POSITION_DATA).append("\": false"); } if (stemmed == true) { VespaSerializer.comma(annotation, initLen); @@ -1050,8 +1033,7 @@ public class VespaSerializer { } if (lowercased == true) { VespaSerializer.comma(annotation, initLen); - annotation.append('"').append(NORMALIZE_CASE) - .append("\": false"); + annotation.append('"').append(NORMALIZE_CASE).append("\": false"); } if (accentDrop == false) { VespaSerializer.comma(annotation, initLen); @@ -1059,13 +1041,11 @@ public class VespaSerializer { } if (andSegmenting == SegmentingRule.BOOLEAN_AND) { VespaSerializer.comma(annotation, initLen); - annotation.append('"').append(AND_SEGMENTING) - .append("\": true"); + annotation.append('"').append(AND_SEGMENTING).append("\": true"); } if (!isFromQuery) { VespaSerializer.comma(annotation, initLen); - annotation.append('"').append(IMPLICIT_TRANSFORMS) - .append("\": false"); + annotation.append('"').append(IMPLICIT_TRANSFORMS).append("\": false"); } if (prefix) { VespaSerializer.comma(annotation, initLen); @@ -1106,9 +1086,9 @@ public class VespaSerializer { dispatchBuilder.put(ONearItem.class, new ONearSerializer()); dispatchBuilder.put(OrItem.class, new OrSerializer()); dispatchBuilder.put(PhraseItem.class, new PhraseSerializer()); + dispatchBuilder.put(SameElementItem.class, new SameElementSerializer()); dispatchBuilder.put(PhraseSegmentItem.class, new PhraseSegmentSerializer()); - dispatchBuilder.put(PredicateQueryItem.class, - new PredicateQuerySerializer()); + dispatchBuilder.put(PredicateQueryItem.class, new PredicateQuerySerializer()); dispatchBuilder.put(PrefixItem.class, new WordSerializer()); // gotcha dispatchBuilder.put(WordAlternativesItem.class, new WordAlternativesSerializer()); dispatchBuilder.put(RangeItem.class, new RangeSerializer()); @@ -1225,24 +1205,20 @@ public class VespaSerializer { return out.toString(); } - private static void serializeWeightedSetContents(StringBuilder destination, - String opName, WeightedSetItem weightedSet) { + private static void serializeWeightedSetContents(StringBuilder destination, String opName, + WeightedSetItem weightedSet) { serializeWeightedSetContents(destination, opName, weightedSet, ""); } - private static void serializeWeightedSetContents( - StringBuilder destination, - String opName, WeightedSetItem weightedSet, - String optionalAnnotations) { + private static void serializeWeightedSetContents(StringBuilder destination, String opName, + WeightedSetItem weightedSet, String optionalAnnotations) { addAnnotations(destination, weightedSet, optionalAnnotations); destination.append(opName).append('(') .append(normalizeIndexName(weightedSet.getIndexName())) .append(", {"); int initLen = destination.length(); - List<Entry<Object, Integer>> tokens = new ArrayList<>( - weightedSet.getNumTokens()); - for (Iterator<Entry<Object, Integer>> i = weightedSet.getTokens(); i - .hasNext();) { + List<Entry<Object, Integer>> tokens = new ArrayList<>(weightedSet.getNumTokens()); + for (Iterator<Entry<Object, Integer>> i = weightedSet.getTokens(); i.hasNext();) { tokens.add(i.next()); } Collections.sort(tokens, tokenComparator); @@ -1255,9 +1231,8 @@ public class VespaSerializer { destination.append("})"); } - private static void addAnnotations( - StringBuilder destination, - WeightedSetItem weightedSet, String optionalAnnotations) { + private static void addAnnotations(StringBuilder destination, WeightedSetItem weightedSet, + String optionalAnnotations) { int preAnnotationValueLen; int incomingLen = destination.length(); String annotations = leafAnnotations(weightedSet); @@ -1303,13 +1278,11 @@ public class VespaSerializer { } if (item.hasExplicitSignificance()) { comma(annotation, initLen); - annotation.append('"').append(SIGNIFICANCE).append("\": ") - .append(significance); + annotation.append('"').append(SIGNIFICANCE).append("\": ").append(significance); } if (uniqueId != 0) { comma(annotation, initLen); - annotation.append('"').append(UNIQUE_ID).append("\": ") - .append(uniqueId); + annotation.append('"').append(UNIQUE_ID).append("\": ").append(uniqueId); } } { @@ -1335,25 +1308,21 @@ public class VespaSerializer { } if (weight != 100) { comma(annotation, initLen); - annotation.append('"').append(WEIGHT).append("\": ") - .append(weight); + annotation.append('"').append(WEIGHT).append("\": ").append(weight); } } if (item instanceof IntItem) { int hitLimit = ((IntItem) item).getHitLimit(); if (hitLimit != 0) { comma(annotation, initLen); - annotation.append('"').append(HIT_LIMIT).append("\": ") - .append(hitLimit); + annotation.append('"').append(HIT_LIMIT).append("\": ").append(hitLimit); } } return annotation.toString(); } - private static void serializeOrigin(StringBuilder destination, - String image, int offset, int length) { - destination.append('"').append(ORIGIN).append("\": {\"") - .append(ORIGIN_ORIGINAL).append("\": \""); + private static void serializeOrigin(StringBuilder destination, String image, int offset, int length) { + destination.append('"').append(ORIGIN).append("\": {\"").append(ORIGIN_ORIGINAL).append("\": \""); escape(image, destination); destination.append("\", \"").append(ORIGIN_OFFSET).append("\": ") .append(offset).append(", \"").append(ORIGIN_LENGTH) diff --git a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java index 259719571be..292bb6d0f5a 100644 --- a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java +++ b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java @@ -47,6 +47,7 @@ import com.yahoo.prelude.query.PrefixItem; import com.yahoo.prelude.query.RangeItem; import com.yahoo.prelude.query.RankItem; import com.yahoo.prelude.query.RegExpItem; +import com.yahoo.prelude.query.SameElementItem; import com.yahoo.prelude.query.SegmentItem; import com.yahoo.prelude.query.SegmentingRule; import com.yahoo.prelude.query.Substring; @@ -161,6 +162,7 @@ public class YqlParser implements Parser { static final String RANGE = "range"; static final String RANKED = "ranked"; static final String RANK = "rank"; + static final String SAME_ELEMENT = "sameElement"; static final String SCORE_THRESHOLD = "scoreThreshold"; static final String SIGNIFICANCE = "significance"; static final String STEM = "stem"; @@ -533,6 +535,17 @@ public class YqlParser implements Parser { } @NonNull + private Item instantiateSameElementItem(String field, OperatorNode<ExpressionOperator> ast) { + assertHasFunctionName(ast, SAME_ELEMENT); + + SameElementItem sameElement = new SameElementItem(field); + for (OperatorNode<ExpressionOperator> word : ast.<List<OperatorNode<ExpressionOperator>>> getArgument(1)) { + sameElement.addItem(buildTermSearch(word)); + } + return leafStyleSettings(ast, sameElement); + } + + @NonNull private Item instantiatePhraseItem(String field, OperatorNode<ExpressionOperator> ast) { assertHasFunctionName(ast, PHRASE); @@ -1183,6 +1196,8 @@ public class YqlParser implements Parser { List<String> names = ast.getArgument(0); Preconditions.checkArgument(names.size() == 1, "Expected 1 name, got %s.", names.size()); switch (names.get(0)) { + case SAME_ELEMENT: + return instantiateSameElementItem(field, ast); case PHRASE: return instantiatePhraseItem(field, ast); case NEAR: @@ -1194,7 +1209,7 @@ public class YqlParser implements Parser { case ALTERNATIVES: return instantiateWordAlternativesItem(field, ast); default: - throw newUnexpectedArgumentException(names.get(0), EQUIV, NEAR, ONEAR, PHRASE); + throw newUnexpectedArgumentException(names.get(0), EQUIV, NEAR, ONEAR, PHRASE, SAME_ELEMENT); } } diff --git a/container-search/src/test/java/com/yahoo/prelude/searcher/test/JuniperSearcherTestCase.java b/container-search/src/test/java/com/yahoo/prelude/searcher/test/JuniperSearcherTestCase.java index f71c0803ce8..9f4a12d24e6 100644 --- a/container-search/src/test/java/com/yahoo/prelude/searcher/test/JuniperSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/searcher/test/JuniperSearcherTestCase.java @@ -28,9 +28,9 @@ import java.util.List; import java.util.Map; /** - * Tests conversion of juniper highlighting to XML + * Tests juniper highlighting * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> + * @author Steinar Knutsen */ public class JuniperSearcherTestCase { diff --git a/container-search/src/test/java/com/yahoo/prelude/searcher/test/QuotingSearcherTestCase.java b/container-search/src/test/java/com/yahoo/prelude/searcher/test/QuotingSearcherTestCase.java index ee735104caa..691f877dfba 100644 --- a/container-search/src/test/java/com/yahoo/prelude/searcher/test/QuotingSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/searcher/test/QuotingSearcherTestCase.java @@ -15,9 +15,9 @@ import com.yahoo.search.Result; import com.yahoo.prelude.fastsearch.FastHit; import com.yahoo.prelude.hitfield.HitField; import com.yahoo.search.Searcher; -import com.yahoo.prelude.searcher.DocumentSourceSearcher; import com.yahoo.prelude.searcher.QuotingSearcher; import com.yahoo.search.searchchain.Execution; +import com.yahoo.search.searchchain.testutil.DocumentSourceSearcher; import org.junit.Test; import java.util.ArrayList; @@ -55,7 +55,7 @@ public class QuotingSearcherTestCase { hit.setRelevance(new Relevance(1)); hit.setField("title", "smith & jones"); r.hits().add(hit); - docsource.addResultSet(q, r); + docsource.addResult(q, r); Result check = doSearch(s, q, 0, 10, chained); assertEquals("smith & jones", check.hits().get(0).getField("title").toString()); assertTrue(check.hits().get(0).fields().containsKey("title")); @@ -75,7 +75,7 @@ public class QuotingSearcherTestCase { hit.setRelevance(new Relevance(1)); hit.setField("title", "&smith &jo& nes"); r.hits().add(hit); - docsource.addResultSet(q, r); + docsource.addResult(q, r); Result check = doSearch(s, q, 0, 10, chained); assertEquals("&smith &jo& nes", check.hits().get(0).getField("title").toString()); assertTrue(check.hits().get(0).fields().containsKey("title")); @@ -95,7 +95,7 @@ public class QuotingSearcherTestCase { hit.setRelevance(new Relevance(1)); hit.setField("title", new HitField("title", "&smith &jo& nes")); r.hits().add(hit); - docsource.addResultSet(q, r); + docsource.addResult(q, r); Result check = doSearch(s, q, 0, 10, chained); assertEquals("&smith &jo& nes", check.hits().get(0).getField("title").toString()); assertTrue(check.hits().get(0).fields().containsKey("title")); @@ -116,7 +116,7 @@ public class QuotingSearcherTestCase { hit.setRelevance(new Relevance(1)); hit.setField("title", Integer.valueOf(42)); r.hits().add(hit); - docsource.addResultSet(q, r); + docsource.addResult(q, r); Result check = doSearch(s, q, 0, 10, chained); // should not quote non-string properties assertEquals(Integer.valueOf(42), check.hits().get(0).getField("title")); diff --git a/container-search/src/test/java/com/yahoo/search/querytransform/test/NGramSearcherTestCase.java b/container-search/src/test/java/com/yahoo/search/querytransform/test/NGramSearcherTestCase.java index 99b7eeff9a0..a3f7ff12319 100644 --- a/container-search/src/test/java/com/yahoo/search/querytransform/test/NGramSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/querytransform/test/NGramSearcherTestCase.java @@ -46,32 +46,32 @@ public class NGramSearcherTestCase { @Before public void setUp() { - searcher=new NGramSearcher(new SimpleLinguistics()); - indexFacts=new IndexFacts(); + searcher = new NGramSearcher(new SimpleLinguistics()); + indexFacts = new IndexFacts(); - Index defaultIndex=new Index("default"); - defaultIndex.setNGram(true,3); + Index defaultIndex = new Index("default"); + defaultIndex.setNGram(true, 3); defaultIndex.setDynamicSummary(true); - indexFacts.addIndex("default",defaultIndex); + indexFacts.addIndex("default", defaultIndex); - Index test=new Index("test"); + Index test = new Index("test"); test.setHighlightSummary(true); - indexFacts.addIndex("default",test); + indexFacts.addIndex("default", test); - Index gram2=new Index("gram2"); - gram2.setNGram(true,2); + Index gram2 = new Index("gram2"); + gram2.setNGram(true, 2); gram2.setDynamicSummary(true); - indexFacts.addIndex("default",gram2); + indexFacts.addIndex("default", gram2); - Index gram3=new Index("gram3"); - gram3.setNGram(true,3); + Index gram3 = new Index("gram3"); + gram3.setNGram(true, 3); gram3.setHighlightSummary(true); - indexFacts.addIndex("default",gram3); + indexFacts.addIndex("default", gram3); - Index gram14=new Index("gram14"); - gram14.setNGram(true,14); + Index gram14 = new Index("gram14"); + gram14.setNGram(true, 14); gram14.setDynamicSummary(true); - indexFacts.addIndex("default",gram14); + indexFacts.addIndex("default", gram14); } private IndexFacts getMixedSetup() { diff --git a/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java index d6bcdf3195f..6984a8537ef 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/VespaSerializerTestCase.java @@ -3,6 +3,7 @@ package com.yahoo.search.yql; import static org.junit.Assert.*; +import com.yahoo.prelude.query.SameElementItem; import com.yahoo.search.Query; import com.yahoo.search.grouping.Continuation; import com.yahoo.search.grouping.GroupingRequest; @@ -218,6 +219,15 @@ public class VespaSerializerTestCase { } @Test + public final void testSameElement() { + SameElementItem sameElement = new SameElementItem("ss"); + sameElement.addItem(new WordItem("a", "f1")); + sameElement.addItem(new WordItem("b", "f2")); + assertEquals("ss:{f1:a f2:b}", sameElement.toString()); + assertEquals("ss contains sameElement(f1 contains ([{\"implicitTransforms\": false}]\"a\"), f2 contains ([{\"implicitTransforms\": false}]\"b\"))", VespaSerializer.serialize(sameElement)); + + } + @Test public final void testAnnotatedAndSegment() { AndSegmentItem andSegment = new AndSegmentItem("abc", true, false); andSegment.addItem(new WordItem("a", "indexNamePlaceholder")); @@ -307,6 +317,7 @@ public class VespaSerializerTestCase { assertEquals("default contains \"nalle\"", q); } + @Test public final void testLongAndNot() { NotItem item = new NotItem(); diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java index 75b39f26625..9d04dc545e1 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java @@ -261,6 +261,12 @@ public class YqlParserTestCase { } @Test + public void testSameElement() { + assertParse("select foo from bar where baz contains sameElement(f1 contains \"a\", f2 contains \"b\");", + "baz:{f1:a f2:b}"); + } + + @Test public void testPhrase() { assertParse("select foo from bar where baz contains phrase(\"a\", \"b\");", "baz:\"a b\""); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java index 9965d88c64e..516cd52d710 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgrader.java @@ -50,11 +50,16 @@ public class SystemUpgrader extends Maintainer { private void deploy(List<SystemApplication> applications, Version target) { for (List<ZoneId> zones : controller().zoneRegistry().upgradePolicy().asList()) { boolean converged = true; - for (SystemApplication application : applications) { - if (application.dependencies().stream().allMatch(dep -> convergedOn(target, dep, zones))) { - deploy(zones, application, target); + for (ZoneId zone : zones) { + for (SystemApplication application : applications) { + boolean dependenciesConverged = application.dependencies().stream() + .filter(applications::contains) // TODO: Remove when all() is used. + .allMatch(dependency -> currentVersion(zone, dependency.id()).equals(target)); + if (dependenciesConverged) { + deploy(target, application, zone); + } + converged &= currentVersion(zone, application.id()).equals(target); } - converged &= convergedOn(target, application, zones); } if (!converged) { break; @@ -63,25 +68,19 @@ public class SystemUpgrader extends Maintainer { } /** Deploy application on given version idempotently */ - private void deploy(List<ZoneId> zones, SystemApplication application, Version target) { - for (ZoneId zone : zones) { - if (!wantedVersion(zone, application.id(), target).equals(target)) { - log.info(String.format("Deploying %s version %s in %s", application.id(), target, zone)); - controller().applications().deploy(application, zone, target); - } + private void deploy(Version target, SystemApplication application, ZoneId zone) { + if (!wantedVersion(zone, application.id(), target).equals(target)) { + log.info(String.format("Deploying %s version %s in %s", application.id(), target, zone)); + controller().applications().deploy(application, zone, target); } } - private boolean convergedOn(Version target, SystemApplication application, List<ZoneId> zones) { - return zones.stream().allMatch(zone -> currentVersion(zone, application.id(), target).equals(target)); - } - private Version wantedVersion(ZoneId zone, ApplicationId application, Version defaultVersion) { return minVersion(zone, application, Node::wantedVersion).orElse(defaultVersion); } - private Version currentVersion(ZoneId zone, ApplicationId application, Version defaultVersion) { - return minVersion(zone, application, Node::currentVersion).orElse(defaultVersion); + private Version currentVersion(ZoneId zone, ApplicationId application) { + return minVersion(zone, application, Node::currentVersion).orElse(Version.emptyVersion); } private Optional<Version> minVersion(ZoneId zone, ApplicationId application, Function<Node, Version> versionField) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java index 3fbda16cb4a..1ec64f8d478 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/SystemUpgraderTest.java @@ -79,12 +79,18 @@ public class SystemUpgraderTest { assertWantedVersion(SystemApplication.configServer, version1, zone2, zone3, zone4); assertWantedVersion(SystemApplication.zone, version1, zone2, zone3, zone4); - // zone 2 and 3: zone-config-server upgrades in parallel + // zone 2 and 3: zone-config-server upgrades, first in zone 2, then in zone 3 tester.systemUpgrader().maintain(); assertWantedVersion(SystemApplication.configServer, version2, zone2, zone3); assertWantedVersion(SystemApplication.configServer, version1, zone4); assertWantedVersion(SystemApplication.zone, version1, zone2, zone3, zone4); - completeUpgrade(SystemApplication.configServer, version2, zone2, zone3); + completeUpgrade(SystemApplication.configServer, version2, zone2); + + // zone-application starts upgrading in zone 2, while zone-config-server completes upgrade in zone 3 + tester.systemUpgrader().maintain(); + assertWantedVersion(SystemApplication.zone, version2, zone2); + assertWantedVersion(SystemApplication.zone, version1, zone3); + completeUpgrade(SystemApplication.configServer, version2, zone3); // zone 2 and 3: zone-application upgrades in parallel tester.systemUpgrader().maintain(); diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp index 837ebd873e3..f9cf3472110 100644 --- a/document/src/vespa/document/select/valuenodes.cpp +++ b/document/src/vespa/document/select/valuenodes.cpp @@ -905,7 +905,7 @@ ArithmeticValueNode::getValue(std::unique_ptr<Value> lval, slval.getValue() + srval.getValue())); } } - //@fallthrough@ + [[fallthrough]]; case SUB: case MUL: case DIV: @@ -995,7 +995,7 @@ ArithmeticValueNode::traceValue(std::unique_ptr<Value> lval, return result; } } - //@fallthrough@ + [[fallthrough]]; case SUB: case MUL: case DIV: diff --git a/fastlib/src/vespa/fastlib/util/base64.cpp b/fastlib/src/vespa/fastlib/util/base64.cpp index 1b7889d8c47..8b9ac45e698 100644 --- a/fastlib/src/vespa/fastlib/util/base64.cpp +++ b/fastlib/src/vespa/fastlib/util/base64.cpp @@ -90,7 +90,7 @@ Fast_Base64::Decode(const char *source, unsigned int length, char *destination) if (symbol != '=' || i == length) return -1; symbol = source[++i]; - //@fallthrough@ + [[fallthrough]]; case 3: for (; i < length; ++i) { symbol = source[i]; if (symbol == '\0') diff --git a/fbench/src/filterfile/filterfile.cpp b/fbench/src/filterfile/filterfile.cpp index ca93b70a046..e9b35de97e0 100644 --- a/fbench/src/filterfile/filterfile.cpp +++ b/fbench/src/filterfile/filterfile.cpp @@ -133,7 +133,7 @@ main(int argc, char** argv) break; case 1: buf[outIdx++] = line[idx]; - //@fallthrough@ + [[fallthrough]]; case 2: if (line[idx++] == '&') state = 0; diff --git a/fsa/src/vespa/fsa/segmenter.cpp b/fsa/src/vespa/fsa/segmenter.cpp index d13249a5ce8..3bcb3f1b489 100644 --- a/fsa/src/vespa/fsa/segmenter.cpp +++ b/fsa/src/vespa/fsa/segmenter.cpp @@ -77,16 +77,16 @@ void Segmenter::Segments::buildSegmentation(Segmenter::SegmentationMethod method switch(method){ case SEGMENTATION_WEIGHTED_BIAS100: bias+=50; - //@fallthrough@ + [[fallthrough]]; case SEGMENTATION_WEIGHTED_BIAS50: bias+=30; - //@fallthrough@ + [[fallthrough]]; case SEGMENTATION_WEIGHTED_BIAS20: bias+=10; - //@fallthrough@ + [[fallthrough]]; case SEGMENTATION_WEIGHTED_BIAS10: bias+=10; - //@fallthrough@ + [[fallthrough]]; case SEGMENTATION_WEIGHTED: bestid=-1; for(i=n_txt;i>=0;i--){ diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java index 24736683845..26ca069aceb 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/IOExceptionUtil.java @@ -7,6 +7,10 @@ import java.nio.file.NoSuchFileException; import java.util.Optional; /** + * Utils related to IOException. + * + * todo: replace much of the below with com.yahoo.yolean.Exceptions::uncheck + * * @author hakonhall */ public class IOExceptionUtil { diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/maintainer/CoreCollector.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/maintainer/CoreCollector.java index fe09f23d282..fef5a695db6 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/maintainer/CoreCollector.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/maintainer/CoreCollector.java @@ -157,7 +157,7 @@ public class CoreCollector { private Path compressCoredump(Path coredumpPath) throws IOException { if (! coredumpPath.toString().endsWith(".lz4")) { processExecuter.exec( - new String[]{LZ4_PATH, coredumpPath.toString(), coredumpPath.toString() + ".lz4"}); + new String[]{LZ4_PATH, "-f", coredumpPath.toString(), coredumpPath.toString() + ".lz4"}); return coredumpPath; } else { @@ -167,7 +167,7 @@ public class CoreCollector { Path decompressedPath = Paths.get(coredumpPath.toString().replaceFirst("\\.lz4$", "")); Pair<Integer, String> result = processExecuter.exec( - new String[]{LZ4_PATH, "-f", "-d", coredumpPath.toString(), decompressedPath.toString()}); + new String[] {LZ4_PATH, "-f", "-d", coredumpPath.toString(), decompressedPath.toString()}); if (result.getFirst() != 0) { throw new RuntimeException("Failed to decompress file " + coredumpPath + ": " + result); } diff --git a/searchlib/src/vespa/searchlib/common/sortresults.cpp b/searchlib/src/vespa/searchlib/common/sortresults.cpp index ed86014f7b3..e39f11f56b2 100644 --- a/searchlib/src/vespa/searchlib/common/sortresults.cpp +++ b/searchlib/src/vespa/searchlib/common/sortresults.cpp @@ -459,16 +459,16 @@ public: default: case 4: r |= _data[a._idx + a._pos + 3] << 0; - //@fallthrough@ + [[fallthrough]]; case 3: r |= _data[a._idx + a._pos + 2] << 8; - //@fallthrough@ + [[fallthrough]]; case 2: r |= _data[a._idx + a._pos + 1] << 16; - //@fallthrough@ + [[fallthrough]]; case 1: r |= _data[a._idx + a._pos + 0] << 24; - //@fallthrough@ + [[fallthrough]]; case 0:; } a._pos += std::min(4u, left); diff --git a/searchlib/src/vespa/searchlib/predicate/predicate_hash.h b/searchlib/src/vespa/searchlib/predicate/predicate_hash.h index 938b1bc5542..861a94d1990 100644 --- a/searchlib/src/vespa/searchlib/predicate/predicate_hash.h +++ b/searchlib/src/vespa/searchlib/predicate/predicate_hash.h @@ -75,30 +75,30 @@ struct PredicateHash { // handle the last 23 bytes c += origLen; switch(len) { // all the case statements fall through - case 23: c+=((0xffLL & aKey[offset+22])<<56); //@fallthrough@ - case 22: c+=((0xffLL & aKey[offset+21])<<48); //@fallthrough@ - case 21: c+=((0xffLL & aKey[offset+20])<<40); //@fallthrough@ - case 20: c+=((0xffLL & aKey[offset+19])<<32); //@fallthrough@ - case 19: c+=((0xffLL & aKey[offset+18])<<24); //@fallthrough@ - case 18: c+=((0xffLL & aKey[offset+17])<<16); //@fallthrough@ - case 17: c+=((0xffLL & aKey[offset+16])<<8); //@fallthrough@ + case 23: c+=((0xffLL & aKey[offset+22])<<56); [[fallthrough]]; + case 22: c+=((0xffLL & aKey[offset+21])<<48); [[fallthrough]]; + case 21: c+=((0xffLL & aKey[offset+20])<<40); [[fallthrough]]; + case 20: c+=((0xffLL & aKey[offset+19])<<32); [[fallthrough]]; + case 19: c+=((0xffLL & aKey[offset+18])<<24); [[fallthrough]]; + case 18: c+=((0xffLL & aKey[offset+17])<<16); [[fallthrough]]; + case 17: c+=((0xffLL & aKey[offset+16])<<8); [[fallthrough]]; // the first byte of c is reserved for the length - case 16: b+=((0xffLL & aKey[offset+15])<<56); //@fallthrough@ - case 15: b+=((0xffLL & aKey[offset+14])<<48); //@fallthrough@ - case 14: b+=((0xffLL & aKey[offset+13])<<40); //@fallthrough@ - case 13: b+=((0xffLL & aKey[offset+12])<<32); //@fallthrough@ - case 12: b+=((0xffLL & aKey[offset+11])<<24); //@fallthrough@ - case 11: b+=((0xffLL & aKey[offset+10])<<16); //@fallthrough@ - case 10: b+=((0xffLL & aKey[offset+ 9])<<8); //@fallthrough@ - case 9: b+=( 0xffLL & aKey[offset+ 8]); //@fallthrough@ - case 8: a+=((0xffLL & aKey[offset+ 7])<<56); //@fallthrough@ - case 7: a+=((0xffLL & aKey[offset+ 6])<<48); //@fallthrough@ - case 6: a+=((0xffLL & aKey[offset+ 5])<<40); //@fallthrough@ - case 5: a+=((0xffLL & aKey[offset+ 4])<<32); //@fallthrough@ - case 4: a+=((0xffLL & aKey[offset+ 3])<<24); //@fallthrough@ - case 3: a+=((0xffLL & aKey[offset+ 2])<<16); //@fallthrough@ - case 2: a+=((0xffLL & aKey[offset+ 1])<<8); //@fallthrough@ - case 1: a+=( 0xffLL & aKey[offset+ 0]); //@fallthrough@ + case 16: b+=((0xffLL & aKey[offset+15])<<56); [[fallthrough]]; + case 15: b+=((0xffLL & aKey[offset+14])<<48); [[fallthrough]]; + case 14: b+=((0xffLL & aKey[offset+13])<<40); [[fallthrough]]; + case 13: b+=((0xffLL & aKey[offset+12])<<32); [[fallthrough]]; + case 12: b+=((0xffLL & aKey[offset+11])<<24); [[fallthrough]]; + case 11: b+=((0xffLL & aKey[offset+10])<<16); [[fallthrough]]; + case 10: b+=((0xffLL & aKey[offset+ 9])<<8); [[fallthrough]]; + case 9: b+=( 0xffLL & aKey[offset+ 8]); [[fallthrough]]; + case 8: a+=((0xffLL & aKey[offset+ 7])<<56); [[fallthrough]]; + case 7: a+=((0xffLL & aKey[offset+ 6])<<48); [[fallthrough]]; + case 6: a+=((0xffLL & aKey[offset+ 5])<<40); [[fallthrough]]; + case 5: a+=((0xffLL & aKey[offset+ 4])<<32); [[fallthrough]]; + case 4: a+=((0xffLL & aKey[offset+ 3])<<24); [[fallthrough]]; + case 3: a+=((0xffLL & aKey[offset+ 2])<<16); [[fallthrough]]; + case 2: a+=((0xffLL & aKey[offset+ 1])<<8); [[fallthrough]]; + case 1: a+=( 0xffLL & aKey[offset+ 0]); // case 0: nothing left to add } diff --git a/staging_vespalib/src/vespa/vespalib/util/jsonwriter.cpp b/staging_vespalib/src/vespa/vespalib/util/jsonwriter.cpp index 8fd96153dd7..ebeda4f1b8b 100644 --- a/staging_vespalib/src/vespa/vespalib/util/jsonwriter.cpp +++ b/staging_vespalib/src/vespa/vespalib/util/jsonwriter.cpp @@ -56,7 +56,7 @@ JSONWriter::quote(const char * str, size_t len) case '\"': case '\\': v[j++] = '\\'; - //@fallthrough@ + [[fallthrough]]; default: v[j++] = str[i]; break; diff --git a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp index e87eabd19df..06dfc073f61 100644 --- a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp +++ b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp @@ -569,7 +569,7 @@ FileStorHandlerImpl::remapMessage(api::StorageMessage& msg, const document::Buck } // Follow onto next to move queue or fail } - //@fallthrough@ + [[fallthrough]]; case api::MessageType::SPLITBUCKET_ID: // Move to correct queue if op == MOVE // Fail with bucket not found if op is JOIN @@ -640,7 +640,7 @@ FileStorHandlerImpl::remapMessage(api::StorageMessage& msg, const document::Buck break; case GetIterCommand::ID: bucket = static_cast<GetIterCommand&>(msg).getBucket(); - //@fallthrough@ + [[fallthrough]]; case RepairBucketCommand::ID: if (bucket.getBucketId().getRawId() == 0) { bucket = static_cast<RepairBucketCommand&>(msg).getBucket(); diff --git a/valgrind-suppressions.txt b/valgrind-suppressions.txt index 92954b39f92..baef981a3f9 100644 --- a/valgrind-suppressions.txt +++ b/valgrind-suppressions.txt @@ -35,6 +35,38 @@ fun:main } { + Bug in cppunit. This suppression is created on CentOS7. + Memcheck:Leak + match-leak-kinds: definite + fun:_Znwm + fun:allocate + fun:_S_create + fun:_S_construct<char const*> + fun:_S_construct_aux<char const*> + fun:_S_construct<char const*> + fun:_ZNSsC1EPKcRKSaIcE + fun:_ZN7CppUnit10TestRunnerC1Ev + fun:_ZN7CppUnit14TextTestRunnerC1EPNS_9OutputterE + fun:_ZN10vdstestlib17CppUnitTestRunner3runEiPPKc + fun:main +} +{ + Bug in cppunit. This suppression is created on CentOS7. + Memcheck:Leak + match-leak-kinds: definite + fun:_Znwm + fun:allocate + fun:_S_create + fun:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag + fun:_S_construct_aux<char const*> + fun:_S_construct<char const*> + fun:_ZNSsC1EPKcRKSaIcE + fun:_ZN7CppUnit10TestRunnerC1Ev + fun:_ZN7CppUnit14TextTestRunnerC1EPNS_9OutputterE + fun:_ZN10vdstestlib17CppUnitTestRunner3runEiPPKc + fun:main +} +{ RHEL6 strlen is eager and will read 16 bytes blocks. Memcheck:Cond fun:__strlen_sse42 diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentFieldTemplate.java b/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentFieldTemplate.java index 7a59be49458..4390f70cac0 100755 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentFieldTemplate.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentFieldTemplate.java @@ -7,7 +7,6 @@ import com.yahoo.document.Field; import com.yahoo.document.datatypes.FieldValue; import com.yahoo.document.datatypes.Raw; import com.yahoo.io.ByteWriter; -import com.yahoo.prelude.templates.Context; import com.yahoo.text.XML; import java.io.IOException; @@ -38,7 +37,7 @@ public class DocumentFieldTemplate extends com.yahoo.prelude.templates.UserTempl } @Override - public void error(Context context, Writer writer) throws IOException { + public void error(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { // Error shouldn't be handled by this template, but rather // delegated to the searcher } @@ -55,7 +54,7 @@ public class DocumentFieldTemplate extends com.yahoo.prelude.templates.UserTempl } @Override - public void header(Context context, Writer writer) throws IOException { + public void header(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { if (wrapXml) { // XML wrapping should only be used for default field rendering writer.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n"); @@ -64,14 +63,14 @@ public class DocumentFieldTemplate extends com.yahoo.prelude.templates.UserTempl } @Override - public void footer(Context context, Writer writer) throws IOException { + public void footer(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { if (wrapXml) { writer.write("</result>\n"); } } @Override - public void hit(Context context, Writer writer) throws IOException { + public void hit(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { DocumentHit hit = (DocumentHit)context.get("hit"); Document doc = hit.getDocument(); // Assume field existence has been checked before we ever get here. @@ -88,11 +87,11 @@ public class DocumentFieldTemplate extends com.yahoo.prelude.templates.UserTempl } @Override - public void hitFooter(Context context, Writer writer) throws IOException { + public void hitFooter(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { } @Override - public void noHits(Context context, Writer writer) throws IOException { + public void noHits(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { } } diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentXMLTemplate.java b/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentXMLTemplate.java index 25ee0ff5d03..b16f39800ef 100755 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentXMLTemplate.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/storage/searcher/DocumentXMLTemplate.java @@ -6,7 +6,6 @@ import com.yahoo.search.Result; import com.yahoo.search.result.ErrorHit; import com.yahoo.search.result.ErrorMessage; import com.yahoo.search.result.HitGroup; -import com.yahoo.prelude.templates.Context; import com.yahoo.search.result.Hit; import com.yahoo.text.XML; @@ -55,7 +54,7 @@ public class DocumentXMLTemplate extends com.yahoo.prelude.templates.UserTemplat } @Override - public void error(Context context, Writer writer) throws IOException { + public void error(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { writer.write("<errors>\n"); // If the error contains no error hits, use a single error with the main // code and description. Otherwise, use the error hits explicitly @@ -72,7 +71,7 @@ public class DocumentXMLTemplate extends com.yahoo.prelude.templates.UserTemplat } @Override - public void header(Context context, Writer writer) throws IOException { + public void header(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); writer.write("<result>\n"); HitGroup rootGroup = ((Result) context.get("result")).hits(); @@ -82,12 +81,12 @@ public class DocumentXMLTemplate extends com.yahoo.prelude.templates.UserTemplat } @Override - public void footer(Context context, Writer writer) throws IOException { + public void footer(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { writer.write("</result>\n"); } @Override - public void hit(Context context, Writer writer) throws IOException { + public void hit(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { Hit hit = (Hit)context.get("hit"); if (hit instanceof DocumentHit) { DocumentHit docHit = (DocumentHit) hit; @@ -110,11 +109,11 @@ public class DocumentXMLTemplate extends com.yahoo.prelude.templates.UserTemplat } @Override - public void hitFooter(Context context, Writer writer) throws IOException { + public void hitFooter(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { } @Override - public void noHits(Context context, Writer writer) throws IOException { + public void noHits(com.yahoo.prelude.templates.Context context, Writer writer) throws IOException { } } diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/ClientFeederV3.java b/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/ClientFeederV3.java index 5f1c96d000f..835a11bf7c2 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/ClientFeederV3.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/ClientFeederV3.java @@ -183,9 +183,9 @@ class ClientFeederV3 { if (! operationId.isPresent()) { return Optional.empty(); } - final DocumentOperationMessageV3 msg; + final DocumentOperationMessageV3 message; try { - msg = getNextMessage(operationId.get(), requestInputStream, settings); + message = getNextMessage(operationId.get(), requestInputStream, settings); } catch (Exception e) { if (log.isLoggable(LogLevel.DEBUG)) { log.log(LogLevel.DEBUG, Exceptions.toMessageString(e), e); @@ -195,8 +195,9 @@ class ClientFeederV3 { continue; } - setRoute(msg, settings); - return Optional.of(msg); + if (message != null) + setRoute(message, settings); + return Optional.ofNullable(message); } } @@ -273,6 +274,7 @@ class ClientFeederV3 { } // protected for mocking + /** Returns the next message in the stream, or null if none */ protected DocumentOperationMessageV3 getNextMessage( String operationId, InputStream requestInputStream, FeederSettings settings) throws Exception { VespaXMLFeedReader.Operation operation = streamReaderV3.getNextOperation(requestInputStream, settings); @@ -285,14 +287,14 @@ class ClientFeederV3 { null); } - DocumentOperationMessageV3 msg = DocumentOperationMessageV3.create(operation, operationId, metric); - if (msg == null) { + DocumentOperationMessageV3 message = DocumentOperationMessageV3.create(operation, operationId, metric); + if (message == null) { // typical end of feed return null; } metric.add(MetricNames.NUM_OPERATIONS, 1, null /*metricContext*/); - log(LogLevel.DEBUG, "Successfully deserialized document id: ", msg.getOperationId()); - return msg; + log(LogLevel.DEBUG, "Successfully deserialized document id: ", message.getOperationId()); + return message; } private void setMessageParameters(DocumentOperationMessageV3 msg, FeederSettings settings) { diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/storage/searcher/GetSearcherTestCase.java b/vespaclient-container-plugin/src/test/java/com/yahoo/storage/searcher/GetSearcherTestCase.java index 2424ce596a3..9d6c8c2feac 100755 --- a/vespaclient-container-plugin/src/test/java/com/yahoo/storage/searcher/GetSearcherTestCase.java +++ b/vespaclient-container-plugin/src/test/java/com/yahoo/storage/searcher/GetSearcherTestCase.java @@ -17,11 +17,9 @@ import com.yahoo.feedapi.FeedContext; import com.yahoo.feedapi.MessagePropertyProcessor; import com.yahoo.messagebus.Message; import com.yahoo.messagebus.routing.Route; -import com.yahoo.prelude.templates.SearchRendererAdaptor; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.rendering.RendererRegistry; import com.yahoo.search.result.Hit; import com.yahoo.search.result.HitGroup; import com.yahoo.search.searchchain.Execution; @@ -740,7 +738,7 @@ public class GetSearcherTestCase { assertEquals("application/octet-stream", result.getTemplating().getTemplates().getMimeType()); ByteArrayOutputStream stream = new ByteArrayOutputStream(); - SearchRendererAdaptor.callRender(stream, result); + com.yahoo.prelude.templates.SearchRendererAdaptor.callRender(stream, result); stream.flush(); byte[] resultBytes = stream.toByteArray(); @@ -769,7 +767,7 @@ public class GetSearcherTestCase { assertEquals("text/fancy", result.getTemplating().getTemplates().getMimeType()); ByteArrayOutputStream stream = new ByteArrayOutputStream(); - SearchRendererAdaptor.callRender(stream, result); + com.yahoo.prelude.templates.SearchRendererAdaptor.callRender(stream, result); stream.flush(); byte[] resultBytes = stream.toByteArray(); diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp index 94e214e9fb9..366111cad0d 100644 --- a/vespalib/src/tests/stllike/hash_test.cpp +++ b/vespalib/src/tests/stllike/hash_test.cpp @@ -434,6 +434,45 @@ TEST("test that for_each member works as std::for_each") { TEST_DO(verify_sum(m, expected_sum)); } +namespace { + +class WrappedKey +{ + std::unique_ptr<const int> _key; +public: + WrappedKey() : _key() { } + WrappedKey(int key) : _key(std::make_unique<const int>(key)) { } + size_t hash() const { return vespalib::hash<int>()(*_key); } + bool operator==(const WrappedKey &rhs) const { return *_key == *rhs._key; } +}; + +} + +TEST("test that hash map can have non-copyable key") +{ + hash_map<WrappedKey, int> m; + EXPECT_TRUE(m.insert(std::make_pair(WrappedKey(4), 5)).second); + WrappedKey testKey(4); + ASSERT_TRUE(m.find(testKey) != m.end()); + EXPECT_EQUAL(5, m.find(testKey)->second); +} + +TEST("test that hash map can have non-copyable value") +{ + hash_map<int, std::unique_ptr<int>> m; + EXPECT_TRUE(m.insert(std::make_pair(4, std::make_unique<int>(5))).second); + EXPECT_TRUE(m[4]); + EXPECT_EQUAL(5, *m[4]); +} + +TEST("test that hash set can have non-copyable key") +{ + hash_set<WrappedKey> m; + EXPECT_TRUE(m.insert(WrappedKey(4)).second); + WrappedKey testKey(4); + ASSERT_TRUE(m.find(testKey) != m.end()); +} + using IntHashSet = hash_set<int>; TEST("test hash set initializer list - empty") diff --git a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp index 18bf5289f0d..72b494e2479 100644 --- a/vespalib/src/vespa/vespalib/data/slime/json_format.cpp +++ b/vespalib/src/vespa/vespalib/data/slime/json_format.cpp @@ -422,7 +422,7 @@ JsonDecoder::decodeNumber(Inserter &inserter) switch (c) { case '+': case '-': case '.': case 'e': case 'E': isLong = false; - //@fallthrough@ + [[fallthrough]]; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': value.push_back(c); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_map.h b/vespalib/src/vespa/vespalib/stllike/hash_map.h index f2431a73f28..6d6498f8e78 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_map.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_map.h @@ -36,6 +36,7 @@ public: size_t size() const { return _ht.size(); } bool empty() const { return _ht.empty(); } insert_result insert(const value_type & value) { return _ht.insert(value); } + insert_result insert(value_type &&value) { return _ht.insert(std::move(value)); } template <typename InputIt> void insert(InputIt first, InputIt last); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.h b/vespalib/src/vespa/vespalib/stllike/hash_set.h index bb16932a990..c4ccc662787 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_set.h +++ b/vespalib/src/vespa/vespalib/stllike/hash_set.h @@ -37,6 +37,7 @@ public: size_t size() const { return _ht.size(); } bool empty() const { return _ht.empty(); } insert_result insert(const K & value); + insert_result insert(K &&value); template<typename InputIt> void insert(InputIt first, InputIt last); void erase(const K & key); diff --git a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp index bd323b2c860..cf6341218f1 100644 --- a/vespalib/src/vespa/vespalib/stllike/hash_set.hpp +++ b/vespalib/src/vespa/vespalib/stllike/hash_set.hpp @@ -74,6 +74,12 @@ hash_set<K, H, EQ, M>::insert(const K & value) { return _ht.insert(value); } +template<typename K, typename H, typename EQ, typename M> +typename hash_set<K, H, EQ, M>::insert_result +hash_set<K, H, EQ, M>::insert(K &&value) { + return _ht.insert(std::move(value)); +} + } #define VESPALIB_HASH_SET_INSTANTIATE(K) \ diff --git a/vespalib/src/vespa/vespalib/util/bobhash.h b/vespalib/src/vespa/vespalib/util/bobhash.h index 2aff09929b2..60cbe2cbca3 100644 --- a/vespalib/src/vespa/vespalib/util/bobhash.h +++ b/vespalib/src/vespa/vespalib/util/bobhash.h @@ -128,18 +128,18 @@ public: c += length; switch(len) /* all the case statements fall through */ { - case 11: c += (static_cast<uint32_t>(k[10]) << 24); //@fallthrough@ - case 10: c += (static_cast<uint32_t>(k[9]) << 16); //@fallthrough@ - case 9 : c += (static_cast<uint32_t>(k[8]) << 8); //@fallthrough@ + case 11: c += (static_cast<uint32_t>(k[10]) << 24); [[fallthrough]]; + case 10: c += (static_cast<uint32_t>(k[9]) << 16); [[fallthrough]]; + case 9 : c += (static_cast<uint32_t>(k[8]) << 8); [[fallthrough]]; /* the first byte of c is reserved for the length */ - case 8 : b += (static_cast<uint32_t>(k[7]) << 24); //@fallthrough@ - case 7 : b += (static_cast<uint32_t>(k[6]) << 16); //@fallthrough@ - case 6 : b += (static_cast<uint32_t>(k[5]) << 8); //@fallthrough@ - case 5 : b += k[4]; //@fallthrough@ - case 4 : a += (static_cast<uint32_t>(k[3]) << 24); //@fallthrough@ - case 3 : a += (static_cast<uint32_t>(k[2]) << 16); //@fallthrough@ - case 2 : a += (static_cast<uint32_t>(k[1]) << 8); //@fallthrough@ - case 1 : a += k[0]; //@fallthrough@ + case 8 : b += (static_cast<uint32_t>(k[7]) << 24); [[fallthrough]]; + case 7 : b += (static_cast<uint32_t>(k[6]) << 16); [[fallthrough]]; + case 6 : b += (static_cast<uint32_t>(k[5]) << 8); [[fallthrough]]; + case 5 : b += k[4]; [[fallthrough]]; + case 4 : a += (static_cast<uint32_t>(k[3]) << 24); [[fallthrough]]; + case 3 : a += (static_cast<uint32_t>(k[2]) << 16); [[fallthrough]]; + case 2 : a += (static_cast<uint32_t>(k[1]) << 8); [[fallthrough]]; + case 1 : a += k[0]; /* case 0: nothing left to add */ } bobhash_mix(a,b,c); diff --git a/vespalog/src/logctl/logctl.cpp b/vespalog/src/logctl/logctl.cpp index 111dfa071bb..a0963b43c34 100644 --- a/vespalog/src/logctl/logctl.cpp +++ b/vespalog/src/logctl/logctl.cpp @@ -116,10 +116,10 @@ main(int argc, char **argv) break; case 'r': doResetLevels = true; - //@fallthrough@ + [[fallthrough]]; case 'c': shouldCreateFile = true; - //@fallthrough@ + [[fallthrough]]; case 'n': shouldCreateEntry = true; break; diff --git a/vsm/src/vespa/vsm/vsm/docsumfilter.cpp b/vsm/src/vespa/vsm/vsm/docsumfilter.cpp index bd57c05f8ac..21fa1d9ed02 100644 --- a/vsm/src/vespa/vsm/vsm/docsumfilter.cpp +++ b/vsm/src/vespa/vsm/vsm/docsumfilter.cpp @@ -197,7 +197,7 @@ DocsumFilter::getFieldValue(const DocsumFieldSpec::FieldIdentifier & fieldId, return _cachedValue.get(); } } - //@fallthrough@ + [[fallthrough]]; default: return fv; } diff --git a/vsm/src/vespa/vsm/vsm/fieldsearchspec.cpp b/vsm/src/vespa/vsm/vsm/fieldsearchspec.cpp index 8855923610c..b21177a6810 100644 --- a/vsm/src/vespa/vsm/vsm/fieldsearchspec.cpp +++ b/vsm/src/vespa/vsm/vsm/fieldsearchspec.cpp @@ -65,7 +65,7 @@ FieldSearchSpec::FieldSearchSpec(const FieldIdT & fid, const vespalib::string & switch(searchDef) { default: LOG(warning, "Unknown searchdef = %d. Defaulting to AUTOUTF8", searchDef); - //@fallthrough@ + [[fallthrough]]; case VsmfieldsConfig::Fieldspec::AUTOUTF8: case VsmfieldsConfig::Fieldspec::NONE: case VsmfieldsConfig::Fieldspec::SSE2UTF8: diff --git a/yolean/src/main/java/com/yahoo/yolean/Exceptions.java b/yolean/src/main/java/com/yahoo/yolean/Exceptions.java index 83c381e586f..82677a14242 100644 --- a/yolean/src/main/java/com/yahoo/yolean/Exceptions.java +++ b/yolean/src/main/java/com/yahoo/yolean/Exceptions.java @@ -1,6 +1,9 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.yolean; +import java.io.IOException; +import java.io.UncheckedIOException; + /** * Helper methods for handling exceptions * @@ -44,4 +47,59 @@ public class Exceptions { return message; } + /** + * Wraps any IOException thrown from a runnable in an UncheckedIOException. + */ + public static void uncheck(RunnableThrowingIOException runnable) { + try { + runnable.run(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Wraps any IOException thrown from a runnable in an UncheckedIOException w/message. + */ + public static void uncheck(RunnableThrowingIOException runnable, String format, String... args) { + try { + runnable.run(); + } catch (IOException e) { + String message = String.format(format, (Object[]) args); + throw new UncheckedIOException(message, e); + } + } + + @FunctionalInterface + public interface RunnableThrowingIOException { + void run() throws IOException; + } + + /** + * Wraps any IOException thrown from a supplier in an UncheckedIOException. + */ + public static <T> T uncheck(SupplierThrowingIOException<T> supplier) { + try { + return supplier.get(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** + * Wraps any IOException thrown from a supplier in an UncheckedIOException w/message. + */ + public static <T> T uncheck(SupplierThrowingIOException<T> supplier, String format, String... args) { + try { + return supplier.get(); + } catch (IOException e) { + String message = String.format(format, (Object[]) args); + throw new UncheckedIOException(message, e); + } + } + + @FunctionalInterface + public interface SupplierThrowingIOException<T> { + T get() throws IOException; + } } diff --git a/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java b/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java index db605609926..31e27fa2675 100644 --- a/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java +++ b/yolean/src/test/java/com/yahoo/yolean/ExceptionsTestCase.java @@ -3,6 +3,9 @@ package com.yahoo.yolean; import org.junit.Test; +import java.io.IOException; +import java.io.UncheckedIOException; + import static org.junit.Assert.assertEquals; /** @@ -21,4 +24,38 @@ public class ExceptionsTestCase { assertEquals("Foo",Exceptions.toMessageString(new Exception(new Exception("Foo")))); } + @Test + public void testUnchecks() { + try { + Exceptions.uncheck(this::throwIO); + } catch (UncheckedIOException e) { + assertEquals("root cause", e.getCause().getMessage()); + } + + try { + Exceptions.uncheck(this::throwIO, "additional %s", "info"); + } catch (UncheckedIOException e) { + assertEquals("additional info", e.getMessage()); + } + + try { + int i = Exceptions.uncheck(this::throwIOWithReturnValue); + } catch (UncheckedIOException e) { + assertEquals("root cause", e.getCause().getMessage()); + } + + try { + int i = Exceptions.uncheck(this::throwIOWithReturnValue, "additional %s", "info"); + } catch (UncheckedIOException e) { + assertEquals("additional info", e.getMessage()); + } + } + + private void throwIO() throws IOException { + throw new IOException("root cause"); + } + + private int throwIOWithReturnValue() throws IOException { + throw new IOException("root cause"); + } } |