diff options
author | Jon Bratseth <bratseth@gmail.com> | 2022-02-25 11:16:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-25 11:16:50 +0100 |
commit | ccaab80aafc8e6b5d1c129d9ee0759285e1b1297 (patch) | |
tree | ab41b8073cb397f4206eea57875d4358699cc101 /config-model/src/main/java/com/yahoo | |
parent | fc1fd0e6d2e2f651d680ee148dc0f5a8d1bddd45 (diff) | |
parent | 9fa74366994fa991c21db246df97377149fc37b9 (diff) |
Merge branch 'master' into bratseth/strict
Diffstat (limited to 'config-model/src/main/java/com/yahoo')
14 files changed, 333 insertions, 155 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAnnotation.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAnnotation.java index 18b507aefa5..a4e38795850 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAnnotation.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAnnotation.java @@ -10,17 +10,15 @@ import java.util.Optional; * possible. Do not put advanced logic here! * @author arnej27959 **/ -class ParsedAnnotation { +class ParsedAnnotation extends ParsedBlock { - private final String name; private ParsedStruct wrappedStruct = null; private final List<String> inherited = new ArrayList<>(); ParsedAnnotation(String name) { - this.name = name; + super(name, "annotation"); } - public String name() { return name; } public List<String> getInherited() { return List.copyOf(inherited); } public Optional<ParsedStruct> getStruct() { return Optional.ofNullable(wrappedStruct); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAttribute.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAttribute.java index 31a87a7b04f..484d56b6e3e 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAttribute.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedAttribute.java @@ -1,30 +1,63 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.searchdefinition.parser; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + /** * This class holds the extracted information after parsing a * "attribute" block, using simple data structures as far as * possible. Do not put advanced logic here! * @author arnej27959 **/ -class ParsedAttribute { +class ParsedAttribute extends ParsedBlock { - private final String name; + private boolean enableBitVectors = false; + private boolean enableOnlyBitVector = false; + private boolean enableFastAccess = false; + private boolean enableFastSearch = false; + private boolean enableHuge = false; + private boolean enableMutable = false; + private boolean enablePaged = false; + private final Map<String, String> aliases = new HashMap<>(); + private ParsedSorting sortInfo = null; + private String distanceMetric = null; ParsedAttribute(String name) { - this.name = name; + super(name, "attribute"); } - public String name() { return name; } + List<String> getAliases() { return List.copyOf(aliases.keySet()); } + String lookupAliasedFrom(String alias) { return aliases.get(alias); } + Optional<String> getDistanceMetric() { return Optional.ofNullable(distanceMetric); } + boolean getEnableBitVectors() { return this.enableBitVectors; } + boolean getEnableOnlyBitVector() { return this.enableOnlyBitVector; } + boolean getFastAccess() { return this.enableFastAccess; } + boolean getFastSearch() { return this.enableFastSearch; } + boolean getHuge() { return this.enableHuge; } + boolean getMutable() { return this.enableMutable; } + boolean getPaged() { return this.enablePaged; } + Optional<ParsedSorting> getSorting() { return Optional.ofNullable(sortInfo); } - void addAlias(String from, String to) {} - void setDistanceMetric(String metric) {} - void setEnableBitVectors(boolean value) {} - void setEnableOnlyBitVector(boolean value) {} - void setFastAccess(boolean value) {} - void setFastSearch(boolean value) {} - void setHuge(boolean value) {} - void setMutable(boolean value) {} - void setPaged(boolean value) {} - void setSorting(ParsedSorting sorting) {} + void addAlias(String from, String to) { + verifyThat(! aliases.containsKey(to), "already has alias", to); + aliases.put(to, from); + } + void setDistanceMetric(String value) { + verifyThat(distanceMetric == null, "already has distance-metric", distanceMetric); + this.distanceMetric = value; + } + void setEnableBitVectors(boolean value) { this.enableBitVectors = value; } + void setEnableOnlyBitVector(boolean value) { this.enableOnlyBitVector = value; } + void setFastAccess(boolean value) { this.enableFastAccess = true; } + void setFastSearch(boolean value) { this.enableFastSearch = true; } + void setHuge(boolean value) { this.enableHuge = true; } + void setMutable(boolean value) { this.enableMutable = true; } + void setPaged(boolean value) { this.enablePaged = true; } + void setSorting(ParsedSorting sorting) { + verifyThat(this.sortInfo == null, "already has sorting"); + this.sortInfo = sorting; + } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java index e20518ec6e2..213733f7722 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedBlock.java @@ -14,12 +14,12 @@ public class ParsedBlock { this.blockType = blockType; } - public String name() { return name; } + public final String name() { return name; } protected void verifyThat(boolean check, String msg, Object ... msgDetails) { if (check) return; var buf = new StringBuilder(); - buf.append(blockType).append(" ").append(name).append(": "); + buf.append(blockType).append(" '").append(name).append("' error: "); buf.append(msg); for (Object detail : msgDetails) { buf.append(" "); diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java index 291b848be47..0b7d0507161 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocument.java @@ -50,5 +50,6 @@ public class ParsedDocument extends ParsedBlock { docAnnotations.put(annName, annotation); } + public String toString() { return "document "+name(); } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocumentSummary.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocumentSummary.java index 079e051709a..65cfa433dc0 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocumentSummary.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedDocumentSummary.java @@ -12,19 +12,17 @@ import java.util.Map; * possible. Do not put advanced logic here! * @author arnej27959 **/ -class ParsedDocumentSummary { +class ParsedDocumentSummary extends ParsedBlock { - private final String name; private boolean omitSummaryFeatures; private boolean fromDisk; private final List<String> inherited = new ArrayList<>(); private final Map<String, ParsedSummaryField> fields = new HashMap<>(); ParsedDocumentSummary(String name) { - this.name = name; + super(name, "document-summary"); } - String name() { return this.name; } boolean getOmitSummaryFeatures() { return omitSummaryFeatures; } boolean getFromDisk() { return fromDisk; } List<ParsedSummaryField> getSummaryFields() { return List.copyOf(fields.values()); } @@ -32,9 +30,7 @@ class ParsedDocumentSummary { void addField(ParsedSummaryField field) { String fieldName = field.name(); - if (fields.containsKey(fieldName)) { - throw new IllegalArgumentException("document-summary "+this.name+" already has field "+fieldName); - } + verifyThat(! fields.containsKey(fieldName), "already has field", fieldName); fields.put(fieldName, field); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedField.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedField.java index 9f3165856b1..9c7400136ab 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedField.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedField.java @@ -3,9 +3,7 @@ package com.yahoo.searchdefinition.parser; import com.yahoo.searchdefinition.document.Stemming; - import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,9 +15,8 @@ import java.util.Optional; * advanced logic here! * @author arnej27959 **/ -class ParsedField { +class ParsedField extends ParsedBlock { - private final String name; private ParsedType type; private boolean hasBolding = false; private boolean isFilter = false; @@ -42,11 +39,10 @@ class ParsedField { private final List<String> queryCommands = new ArrayList<>(); ParsedField(String name, ParsedType type) { - this.name = name; + super(name, "field"); this.type = type; } - String name() { return this.name; } ParsedType getType() { return this.type; } boolean getBolding() { return this.hasBolding; } boolean getFilter() { return this.isFilter; } @@ -66,18 +62,43 @@ class ParsedField { Optional<ParsedSorting> getSorting() { return Optional.ofNullable(sortSettings); } Map<String, String> getRankTypes() { return Map.copyOf(rankTypes); } - void addAlias(String from, String to) { - if (aliases.containsKey(to)) { - throw new IllegalArgumentException("field "+this.name+" already has alias "+to); + /** get an existing summary field for modification, or create it */ + ParsedSummaryField summaryFieldFor(String name) { + if (summaryFields.containsKey(name)) { + return summaryFields.get(name); } + var sf = new ParsedSummaryField(name, getType()); + summaryFields.put(name, sf); + return sf; + } + + /** get an existing summary field for modification, or create it */ + ParsedSummaryField summaryFieldFor(String name, ParsedType type) { + if (summaryFields.containsKey(name)) { + var sf = summaryFields.get(name); + if (sf.getType() == null) { + sf.setType(type); + } else { + // TODO check that types are properly equal here + String oldName = sf.getType().name(); + String newName = type.name(); + verifyThat(newName.equals(oldName), "type mismatch for summary field", name, ":", oldName, "/", newName); + } + return sf; + } + var sf = new ParsedSummaryField(name, type); + summaryFields.put(name, sf); + return sf; + } + + void addAlias(String from, String to) { + verifyThat(! aliases.containsKey(to), "already has alias", to); aliases.put(to, from); } void addIndex(ParsedIndex index) { String idxName = index.name(); - if (fieldIndexes.containsKey(idxName)) { - throw new IllegalArgumentException("field "+this.name+" already has index "+idxName); - } + verifyThat(! fieldIndexes.containsKey(idxName), "already has index", idxName); fieldIndexes.put(idxName, index); } @@ -100,23 +121,17 @@ class ParsedField { void addAttribute(ParsedAttribute attribute) { String attrName = attribute.name(); - if (attributes.containsKey(attrName)) { - throw new IllegalArgumentException("field "+this.name+" already has attribute "+attrName); - } + verifyThat(! attributes.containsKey(attrName), "already has attribute", attrName); attributes.put(attrName, attribute); } void setIndexingOperation(ParsedIndexingOp idxOp) { - if (indexingOp != null) { - throw new IllegalArgumentException("field "+this.name+" already has indexing"); - } + verifyThat(indexingOp == null, "already has indexing"); indexingOp = idxOp; } void setSorting(ParsedSorting sorting) { - if (sortSettings != null) { - throw new IllegalArgumentException("field "+this.name+" already has sorting"); - } + verifyThat(sortSettings == null, "already has sorting"); this.sortSettings = sorting; } @@ -126,17 +141,13 @@ class ParsedField { void addStructField(ParsedField structField) { String fieldName = structField.name(); - if (structFields.containsKey(fieldName)) { - throw new IllegalArgumentException("field "+this.name+" already has struct-field "+fieldName); - } + verifyThat(! structFields.containsKey(fieldName), "already has struct-field", fieldName); structFields.put(fieldName, structField); } void addSummaryField(ParsedSummaryField summaryField) { String fieldName = summaryField.name(); - if (summaryFields.containsKey(fieldName)) { - throw new IllegalArgumentException("field "+this.name+" already has summary field "+fieldName); - } + verifyThat(! summaryFields.containsKey(fieldName), "already has summary field", fieldName); summaryFields.put(fieldName, summaryField); } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedFieldSet.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedFieldSet.java index 162ce7bb576..30597a6dc42 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedFieldSet.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedFieldSet.java @@ -9,18 +9,16 @@ import java.util.List; * advanced logic here! * @author arnej27959 **/ -class ParsedFieldSet { +class ParsedFieldSet extends ParsedBlock { - private final String name; private final List<String> fields = new ArrayList<>(); private final List<String> queryCommands = new ArrayList<>(); private final ParsedMatchSettings matchInfo = new ParsedMatchSettings(); ParsedFieldSet(String name) { - this.name = name; + super(name, "fieldset"); } - String name() { return this.name; } ParsedMatchSettings matchSettings() { return this.matchInfo; } List<String> getQueryCommands() { return List.copyOf(queryCommands); } List<String> getFieldNames() { return List.copyOf(fields); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedIndex.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedIndex.java index 51ffbfdfc06..dfc9d911f57 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedIndex.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedIndex.java @@ -13,9 +13,8 @@ import java.util.List; * advanced logic here! * @author arnej27959 **/ -class ParsedIndex { +class ParsedIndex extends ParsedBlock { - private final String name; private boolean enableBm25 = false; private boolean isPrefix = false; private HnswIndexParams hnswParams; @@ -27,10 +26,9 @@ class ParsedIndex { private Double densePLT; ParsedIndex(String name) { - this.name = name; + super(name, "index"); } - String name() { return this.name; } boolean getEnableBm25() { return this.enableBm25; } boolean getPrefix() { return this.isPrefix; } HnswIndexParams getHnswIndexParams() { return this.hnswParams; } @@ -41,7 +39,6 @@ class ParsedIndex { Long getLowerBound() { return this.lowerBound; } Long getUpperBound() { return this.upperBound; } Double getDensePostingListThreshold() { return this.densePLT; } - void addAlias(String alias) { aliases.add(alias); diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankFunction.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankFunction.java index 0c501628954..a8ee9a24e69 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankFunction.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankFunction.java @@ -10,26 +10,22 @@ import java.util.List; * far as possible. Do not put advanced logic here! * @author arnej27959 **/ -class ParsedRankFunction { +class ParsedRankFunction extends ParsedBlock { - private final String name; private boolean inline; private String expression; private final List<String> parameters = new ArrayList<>(); ParsedRankFunction(String name) { - this.name = name; + super(name, "function"); } - String name() { return this.name; } boolean getInline() { return this.inline; } String getExpression() { return this.expression; } List<String> getParameters() { return List.copyOf(parameters); } void addParameter(String param) { - if (parameters.contains(param)) { - throw new IllegalArgumentException("function "+this.name+" cannot have parameter "+param+" twice"); - } + verifyThat(! parameters.contains(param), "cannot have parameter", param, "twice"); parameters.add(param); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java index c5f4ea812e2..6fce026948d 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java @@ -7,6 +7,12 @@ import com.yahoo.searchlib.rankingexpression.FeatureList; import com.yahoo.searchlib.rankingexpression.evaluation.TensorValue; import com.yahoo.searchlib.rankingexpression.evaluation.Value; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + /** * This class holds the extracted information after parsing a * rank-profile block in a schema (.sd) file, using simple data @@ -14,43 +20,182 @@ import com.yahoo.searchlib.rankingexpression.evaluation.Value; * * @author arnej27959 */ -class ParsedRankProfile { +class ParsedRankProfile extends ParsedBlock { - private final String name; + private boolean ignoreDefaultRankFeatures = false; + private Double rankScoreDropLimit = null; + private Double termwiseLimit = null; + private FeatureList matchFeatures = null; + private FeatureList rankFeatures = null; + private FeatureList summaryFeatures = null; + private Integer keepRankCount = null; + private Integer minHitsPerThread = null; + private Integer numSearchPartitions = null; + private Integer numThreadsPerSearch = null; + private Integer reRankCount = null; + private MatchPhaseSettings matchPhaseSettings = null; + private String firstPhaseExpression = null; + private String inheritedSummaryFeatures = null; + private String inheritedMatchFeatures = null; + private String secondPhaseExpression = null; + private Boolean strict = null; + private final List<String> inherited = new ArrayList<>(); + private final Map<String, Boolean> fieldsRankFilter = new HashMap<>(); + private final Map<String, Integer> fieldsRankWeight = new HashMap<>(); + private final Map<String, ParsedRankFunction> functions = new HashMap<>(); + private final Map<String, String> fieldsRankType = new HashMap<>(); + private final Map<String, String> rankProperties = new HashMap<>(); + private final Map<String, Value> constants = new HashMap<>(); ParsedRankProfile(String name) { - this.name = name; + super(name, "rank-profile"); + } + + boolean getIgnoreDefaultRankFeatures() { return this.ignoreDefaultRankFeatures; } + Optional<Double> getRankScoreDropLimit() { return Optional.ofNullable(this.rankScoreDropLimit); } + Optional<Double> getTermwiseLimit() { return Optional.ofNullable(this.termwiseLimit); } + Optional<FeatureList> getMatchFeatures() { return Optional.ofNullable(this.matchFeatures); } + Optional<FeatureList> getRankFeatures() { return Optional.ofNullable(this.rankFeatures); } + Optional<FeatureList> getSummaryFeatures() { return Optional.ofNullable(this.summaryFeatures); } + Optional<Integer> getKeepRankCount() { return Optional.ofNullable(this.keepRankCount); } + Optional<Integer> getMinHitsPerThread() { return Optional.ofNullable(this.minHitsPerThread); } + Optional<Integer> getNumSearchPartitions() { return Optional.ofNullable(this.numSearchPartitions); } + Optional<Integer> getNumThreadsPerSearch() { return Optional.ofNullable(this.numThreadsPerSearch); } + Optional<Integer> getReRankCount() { return Optional.ofNullable(this.reRankCount); } + Optional<MatchPhaseSettings> getMatchPhaseSettings() { return Optional.ofNullable(this.matchPhaseSettings); } + Optional<String> getFirstPhaseExpression() { return Optional.ofNullable(this.firstPhaseExpression); } + Optional<String> getInheritedMatchFeatures() { return Optional.ofNullable(this.inheritedMatchFeatures); } + List<ParsedRankFunction> getFunctions() { return List.copyOf(functions.values()); } + List<String> getInherited() { return List.copyOf(inherited); } + Map<String, Boolean> getFieldsWithRankFilter() { return Map.copyOf(fieldsRankFilter); } + Map<String, Integer> getFieldsWithRankWeight() { return Map.copyOf(fieldsRankWeight); } + Map<String, String> getFieldsWithRankType() { return Map.copyOf(fieldsRankType); } + Map<String, String> getRankProperties() { return Map.copyOf(rankProperties); } + Map<String, Value> getConstants() { return Map.copyOf(constants); } + Optional<String> getInheritedSummaryFeatures() { return Optional.ofNullable(this.inheritedSummaryFeatures); } + Optional<String> getSecondPhaseExpression() { return Optional.ofNullable(this.secondPhaseExpression); } + Optional<Boolean> isStrict() { return Optional.ofNullable(this.strict); } + + void addSummaryFeatures(FeatureList features) { + verifyThat(summaryFeatures == null, "already has summary-features"); + this.summaryFeatures = features; + } + + void addMatchFeatures(FeatureList features) { + verifyThat(matchFeatures == null, "already has match-features"); + this.matchFeatures = features; } - public String name() { return name; } + void addRankFeatures(FeatureList features) { + verifyThat(rankFeatures == null, "already has rank-features"); + this.rankFeatures = features; + } + + void inherit(String other) { inherited.add(other); } + + void setInheritedSummaryFeatures(String other) { + verifyThat(inheritedSummaryFeatures == null, "already inherits summary-features"); + this.inheritedSummaryFeatures = other; + } - void addSummaryFeatures(FeatureList features) {} - void addMatchFeatures(FeatureList features) {} - void addRankFeatures(FeatureList features) {} + void addConstant(String name, Value value) { + verifyThat(! constants.containsKey(name), "already has constant", name); + constants.put(name, value); + } - void inherit(String other) {} - void setInheritedSummaryFeatures(String other) {} + void addConstantTensor(String name, TensorValue value) { + verifyThat(! constants.containsKey(name), "already has constant", name); + constants.put(name, value); + } + + void addFieldRankFilter(String field, boolean filter) { + fieldsRankFilter.put(field, filter); + } + + void addFieldRankType(String field, String type) { + verifyThat(! fieldsRankType.containsKey(field), "already has rank type for field", field); + fieldsRankType.put(field, type); + } + + void addFieldRankWeight(String field, int weight) { + verifyThat(! fieldsRankType.containsKey(field), "already has weight for field", field); + fieldsRankWeight.put(field, weight); + } + + void addFunction(ParsedRankFunction func) { + verifyThat(! functions.containsKey(func.name()), "already has function", func.name()); + functions.put(func.name(), func); + } - void addFieldRankType(String field, String type) {} - void addFieldRankWeight(String field, int weight) {} - void addFieldRankFilter(String field, boolean filter) {} - void setSecondPhaseRanking(String expression) {} - void setRerankCount(int count) {} - void setFirstPhaseRanking(String expression) {} - void setKeepRankCount(int count) {} - void setRankScoreDropLimit(double limit) {} - void setMatchPhaseSettings(MatchPhaseSettings settings) {} - void addFunction(ParsedRankFunction func) {} void addMutateOperation(MutateOperation.Phase phase, String attrName, String operation) {} - void setIgnoreDefaultRankFeatures(boolean ignore) {} - void setNumThreadsPerSearch(int threads) {} - void setMinHitsPerThread(int minHits) {} - void setNumSearchPartitions(int numParts) {} - void setTermwiseLimit(double limit) {} - void setInheritedMatchFeatures(String other) {} - void addRankProperty(String key, String value) {} - void addConstant(String name, Value value) {} - void addConstantTensor(String name, TensorValue value) {} - void setStrict(boolean strict) {} + void addRankProperty(String key, String value) { + verifyThat(! rankProperties.containsKey(key), "already has value for rank property", key); + rankProperties.put(key, value); + } + + void setFirstPhaseRanking(String expression) { + verifyThat(firstPhaseExpression == null, "already has first-phase expression"); + this.firstPhaseExpression = expression; + } + + void setIgnoreDefaultRankFeatures(boolean value) { + this.ignoreDefaultRankFeatures = value; + } + + void setInheritedMatchFeatures(String other) { + this.inheritedMatchFeatures = other; + } + + void setKeepRankCount(int count) { + verifyThat(keepRankCount == null, "already has rerank-count"); + this.keepRankCount = count; + } + + void setMatchPhaseSettings(MatchPhaseSettings settings) { + verifyThat(matchPhaseSettings == null, "already has match-phase"); + this.matchPhaseSettings = settings; + } + + void setMinHitsPerThread(int minHits) { + verifyThat(minHitsPerThread == null, "already has min-hits-per-thread"); + this.minHitsPerThread = minHits; + } + + void setNumSearchPartitions(int numParts) { + verifyThat(numSearchPartitions == null, "already has num-search-partitions"); + this.numSearchPartitions = numParts; + } + + void setNumThreadsPerSearch(int threads) { + verifyThat(numThreadsPerSearch == null, "already has num-threads-per-search"); + this.numThreadsPerSearch = threads; + } + + void setRankScoreDropLimit(double limit) { + verifyThat(rankScoreDropLimit == null, "already has rank-score-drop-limit"); + this.rankScoreDropLimit = limit; + } + + void setRerankCount(int count) { + verifyThat(reRankCount == null, "already has rerank-count"); + this.reRankCount = count; + } + + void setSecondPhaseRanking(String expression) { + verifyThat(secondPhaseExpression == null, "already has second-phase expression"); + this.secondPhaseExpression = expression; + } + + void setStrict(boolean strict) { + verifyThat(this.strict == null, "already has strict"); + this.strict = strict; + } + + void setTermwiseLimit(double limit) { + verifyThat(termwiseLimit == null, "already has termwise-limit"); + this.termwiseLimit = limit; + } + + } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSchema.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSchema.java index 2f8c90f9701..9bdd6a0409d 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSchema.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSchema.java @@ -16,7 +16,7 @@ import java.util.Map; * as far as possible. Do not put advanced logic here! * @author arnej27959 **/ -public class ParsedSchema { +public class ParsedSchema extends ParsedBlock { public static class ImportedField { public final String asFieldName; @@ -29,7 +29,6 @@ public class ParsedSchema { } } - private final String name; private boolean rawAsBase64 = false; // TODO Vespa 8 flip default private ParsedDocument myDocument = null; private Stemming defaultStemming = null; @@ -45,11 +44,10 @@ public class ParsedSchema { private final Map<String, ParsedRankProfile> rankProfiles = new HashMap<>(); private final Map<String, ParsedStruct> extraStructs = new HashMap<>(); - public ParsedSchema(String name) { - this.name = name; + public ParsedSchema(String name) { + super(name, "schema"); } - String name() { return name; } boolean getRawAsBase64() { return rawAsBase64; } boolean hasDocument() { return myDocument != null; } ParsedDocument getDocument() { return myDocument; } @@ -69,41 +67,31 @@ public class ParsedSchema { void addAnnotation(ParsedAnnotation annotation) { String annName = annotation.name(); - if (extraAnnotations.containsKey(annName)) { - throw new IllegalArgumentException("schema "+this.name+" already has annotation "+annName); - } + verifyThat(! extraAnnotations.containsKey(annName), "already has annotation", annName); extraAnnotations.put(annName, annotation); } void addDocument(ParsedDocument document) { - if (myDocument != null) { - throw new IllegalArgumentException("schema "+this.name+" already has "+myDocument.name() - + "cannot add document "+document.name()); - } - myDocument = document; + verifyThat(myDocument == null, + "already has", myDocument, "so cannot add", document); + this.myDocument = document; } void addDocumentSummary(ParsedDocumentSummary docsum) { String dsName = docsum.name(); - if (docSums.containsKey(dsName)) { - throw new IllegalArgumentException("schema "+this.name+" already has document-summary "+dsName); - } + verifyThat(! docSums.containsKey(dsName), "already has document-summary", dsName); docSums.put(dsName, docsum); } void addField(ParsedField field) { String fieldName = field.name(); - if (extraFields.containsKey(fieldName)) { - throw new IllegalArgumentException("schema "+this.name+" already has field "+fieldName); - } + verifyThat(! extraFields.containsKey(fieldName), "already has field", fieldName); extraFields.put(fieldName, field); } void addFieldSet(ParsedFieldSet fieldSet) { String fsName = fieldSet.name(); - if (fieldSets.containsKey(fsName)) { - throw new IllegalArgumentException("schema "+this.name+" already has fieldset "+fsName); - } + verifyThat(! fieldSets.containsKey(fsName), "already has fieldset", fsName); fieldSets.put(fsName, fieldSet); } @@ -113,9 +101,7 @@ public class ParsedSchema { void addIndex(ParsedIndex index) { String idxName = index.name(); - if (extraIndexes.containsKey(idxName)) { - throw new IllegalArgumentException("schema "+this.name+" already has index "+idxName); - } + verifyThat(! extraIndexes.containsKey(idxName), "already has index", idxName); extraIndexes.put(idxName, index); } @@ -125,9 +111,7 @@ public class ParsedSchema { void addRankProfile(ParsedRankProfile profile) { String rpName = profile.name(); - if (rankProfiles.containsKey(rpName)) { - throw new IllegalArgumentException("schema "+this.name+" already has rank-profile "+rpName); - } + verifyThat(! rankProfiles.containsKey(rpName), "already has rank-profile", rpName); rankProfiles.put(rpName, profile); } @@ -137,9 +121,7 @@ public class ParsedSchema { void addStruct(ParsedStruct struct) { String sName = struct.name(); - if (extraStructs.containsKey(sName)) { - throw new IllegalArgumentException("schema "+this.name+" already has struct "+sName); - } + verifyThat(! extraStructs.containsKey(sName), "already has struct", sName); extraStructs.put(sName, struct); } @@ -150,10 +132,8 @@ public class ParsedSchema { void inherit(String other) { inherited.add(other); } void setStemming(Stemming value) { - if ((defaultStemming != null) && (defaultStemming != value)) { - throw new IllegalArgumentException("schema " + this.name + " already has stemming " - + defaultStemming + "cannot also set " + value); - } + verifyThat((defaultStemming == null) || (defaultStemming == value), + "already has stemming", defaultStemming, "cannot also set", value); defaultStemming = value; } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSorting.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSorting.java index 2a090e94312..d4686c594da 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSorting.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSorting.java @@ -1,23 +1,49 @@ package com.yahoo.searchdefinition.parser; +import java.util.Optional; + /** * This class holds the extracted information after parsing a "sorting" * block, using simple data structures as far as possible. Do not put * advanced logic here! * @author arnej27959 **/ -class ParsedSorting { +class ParsedSorting extends ParsedBlock { enum Function { RAW, LOWERCASE, UCA } enum Strength { PRIMARY, SECONDARY, TERTIARY, QUATERNARY, IDENTICAL } - void setAscending() {} - void setDescending() {} + private boolean ascending = true; + private Function sortFunction = null; + private Strength sortStrength = null; + private String sortLocale = null; + + ParsedSorting(String blockName, String blockType) { + super(blockName, blockType); + } + + boolean getAscending() { return this.ascending; } + boolean getDescending() { return ! this.ascending; } + Optional<Function> getFunction() { return Optional.ofNullable(sortFunction); } + Optional<Strength> getStrength() { return Optional.ofNullable(sortStrength); } + Optional<String> getLocale() { return Optional.ofNullable(sortLocale); } + + void setAscending() { this.ascending = true; } - void setLocale(String locale) {} + void setDescending() { this.ascending = false; } - void setFunction(Function func) {} - void setStrength(Strength strength) {} + void setLocale(String value) { + verifyThat(sortLocale == null, "sorting already has locale", sortLocale); + this.sortLocale = value; + } + void setFunction(Function value) { + verifyThat(sortFunction == null, "sorting already has function", sortFunction); + this.sortFunction = value; + } + void setStrength(Strength value) { + verifyThat(sortStrength == null, "sorting already has strength", sortStrength); + this.sortStrength = value; + } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedStruct.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedStruct.java index dc95af0ccb4..67f2f137bc1 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedStruct.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedStruct.java @@ -12,24 +12,20 @@ import java.util.Map; * advanced logic here! * @author arnej27959 **/ -public class ParsedStruct { - private final String name; +public class ParsedStruct extends ParsedBlock { private final List<String> inherited = new ArrayList<>(); private final Map<String, ParsedField> fields = new HashMap<>(); public ParsedStruct(String name) { - this.name = name; + super(name, "struct"); } - String name() { return this.name; } List<ParsedField> getFields() { return List.copyOf(fields.values()); } List<String> getInherited() { return List.copyOf(inherited); } void addField(ParsedField field) { String fieldName = field.name(); - if (fields.containsKey(fieldName)) { - throw new IllegalArgumentException("struct "+this.name+" already has field "+fieldName); - } + verifyThat(! fields.containsKey(fieldName), "already has field", fieldName); fields.put(fieldName, field); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSummaryField.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSummaryField.java index 5d4bb23333b..40e95045afd 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSummaryField.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedSummaryField.java @@ -11,10 +11,9 @@ import java.util.List; * possible. Do not put advanced logic here! * @author arnej27959 **/ -class ParsedSummaryField { +class ParsedSummaryField extends ParsedBlock { - private final String name; - private final ParsedType type; + private ParsedType type; private boolean isDyn = false; private boolean isMEO = false; private boolean isFull = false; @@ -23,17 +22,15 @@ class ParsedSummaryField { private final List<String> destinations = new ArrayList<>(); ParsedSummaryField(String name) { - this.name = name; - this.type = null; + this(name, null); } ParsedSummaryField(String name, ParsedType type) { - this.name = name; + super(name, "summary field"); this.type = type; } - String name() { return name; } - ParsedType type() { return type; } + ParsedType getType() { return type; } List<String> getDestinations() { return List.copyOf(destinations); } List<String> getSources() { return List.copyOf(sources); } boolean getBolded() { return isBold; } @@ -47,4 +44,8 @@ class ParsedSummaryField { void setDynamic() { this.isDyn = true; } void setFull() { this.isFull = true; } void setMatchedElementsOnly() { this.isMEO = true; } + void setType(ParsedType value) { + verifyThat(type == null, "Cannot change type from ", type, "to", value); + this.type = value; + } } |