diff options
187 files changed, 1369 insertions, 252 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java index 702eba8c8b5..6960a0a8afd 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java @@ -775,7 +775,7 @@ public class RankProfile implements Cloneable { final Phase phase; final String attribute; final String operation; - MutateOperation(Phase phase, String attribute, String operation) { + public MutateOperation(Phase phase, String attribute, String operation) { this.phase = phase; this.attribute = attribute; this.operation = operation; @@ -785,7 +785,7 @@ public class RankProfile implements Cloneable { public void addMutateOperation(MutateOperation.Phase phase, String attribute, String operation) { mutateOperations.add(new MutateOperation(phase, attribute, operation)); - String prefix = "vespa.mutate." + phase.toString().replace('-', '_'); + String prefix = "vespa.mutate." + phase.toString(); addRankProperty(prefix + ".attribute", attribute); addRankProperty(prefix + ".operation", operation); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/InheritanceResolver.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/InheritanceResolver.java new file mode 100644 index 00000000000..488464ccd1f --- /dev/null +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/InheritanceResolver.java @@ -0,0 +1,105 @@ +// 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.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Class resolving some inheritance relationships. + * + * @author arnej27959 + **/ +public class InheritanceResolver { + + private final Map<String, ParsedSchema> parsedSchemas; + private final Map<String, ParsedDocument> parsedDocs = new HashMap<>(); + + public InheritanceResolver(Map<String, ParsedSchema> parsedSchemas) { + this.parsedSchemas = parsedSchemas; + } + + private void inheritanceCycleCheck(ParsedSchema schema, List<String> seen) { + String name = schema.name(); + if (seen.contains(name)) { + seen.add(name); + throw new IllegalArgumentException("Inheritance cycle for schemas: " + + String.join(" -> ", seen)); + } + seen.add(name); + for (ParsedSchema parent : schema.getResolvedInherits()) { + inheritanceCycleCheck(parent, seen); + } + seen.remove(name); + } + + private void resolveSchemaInheritance() { + for (ParsedSchema schema : parsedSchemas.values()) { + for (String inherit : schema.getInherited()) { + var parent = parsedSchemas.get(inherit); + if (parent == null) { + throw new IllegalArgumentException("schema " + schema.name() + " inherits from unavailable schema " + inherit); + } + schema.resolveInherit(inherit, parent); + } + } + } + + private void checkSchemaCycles() { + List<String> seen = new ArrayList<>(); + for (ParsedSchema schema : parsedSchemas.values()) { + inheritanceCycleCheck(schema, seen); + } + } + + private void resolveDocumentInheritance() { + for (ParsedSchema schema : parsedSchemas.values()) { + if (! schema.hasDocument()) { + // TODO: is schema without a document even valid? + continue; + } + ParsedDocument doc = schema.getDocument(); + var old = parsedDocs.put(doc.name(), doc); + assert(old == null); + } + for (ParsedDocument doc : parsedDocs.values()) { + for (String inherit : doc.getInherited()) { + var parentDoc = parsedDocs.get(inherit); + if (parentDoc == null) { + throw new IllegalArgumentException("document " + doc.name() + " inherits from unavailable document " + inherit); + } + doc.resolveInherit(inherit, parentDoc); + } + } + } + + private void inheritanceCycleCheck(ParsedDocument document, List<String> seen) { + String name = document.name(); + if (seen.contains(name)) { + seen.add(name); + throw new IllegalArgumentException("Inheritance cycle for documents: " + + String.join(" -> ", seen)); + } + seen.add(name); + for (ParsedDocument parent : document.getResolvedInherits()) { + inheritanceCycleCheck(parent, seen); + } + seen.remove(name); + } + + private void checkDocumentCycles() { + List<String> seen = new ArrayList<>(); + for (ParsedDocument doc : parsedDocs.values()) { + inheritanceCycleCheck(doc, seen); + } + } + + public void resolveInheritance() { + resolveSchemaInheritance(); + resolveDocumentInheritance(); + checkSchemaCycles(); + checkDocumentCycles(); + } + +} diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/IntermediateCollection.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/IntermediateCollection.java new file mode 100644 index 00000000000..a93fb441563 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/IntermediateCollection.java @@ -0,0 +1,146 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.parser; + +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.config.model.api.ModelContext; +import com.yahoo.config.model.application.provider.BaseDeployLogger; +import com.yahoo.config.model.deploy.TestProperties; +import com.yahoo.io.IOUtils; +import com.yahoo.io.reader.NamedReader; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Class wrapping parsing of schema files and holding a collection of + * schemas in the intermediate format. + * + * @author arnej27959 + **/ +public class IntermediateCollection { + + private final DeployLogger deployLogger; + private final ModelContext.Properties modelProperties; + + private Map<String, ParsedSchema> parsedSchemas = new HashMap<>(); + + IntermediateCollection() { + this.deployLogger = new BaseDeployLogger(); + this.modelProperties = new TestProperties(); + } + + public IntermediateCollection(DeployLogger logger, ModelContext.Properties properties) { + this.deployLogger = logger; + this.modelProperties = properties; + } + + public Map<String, ParsedSchema> getParsedSchemas() { return Map.copyOf(parsedSchemas); } + + public ParsedSchema getParsedSchema(String name) { return parsedSchemas.get(name); } + + ParsedSchema addSchemaFromString(String input) throws ParseException { + var stream = new SimpleCharStream(input); + var parser = new IntermediateParser(stream, deployLogger, modelProperties); + var schema = parser.schema(); + if (parsedSchemas.containsKey(schema.name())) { + throw new IllegalArgumentException("Duplicate schemas named: " + schema.name()); + } + parsedSchemas.put(schema.name(), schema); + return schema; + } + + private void addSchemaFromStringWithFileName(String input, String fileName) throws ParseException { + var parsed = addSchemaFromString(input); + String nameFromFile = baseName(fileName); + if (! parsed.name().equals(nameFromFile)) { + throw new IllegalArgumentException("The file containing schema '" + + parsed.name() + "' must be named '" + + parsed.name() + ApplicationPackage.SD_NAME_SUFFIX + + "', was '" + stripDirs(fileName) + "'"); + } + } + + private String baseName(String filename) { + int pos = filename.lastIndexOf('/'); + if (pos != -1) { + filename = filename.substring(pos + 1); + } + pos = filename.lastIndexOf('.'); + if (pos != -1) { + filename = filename.substring(0, pos); + } + return filename; + } + + private String stripDirs(String filename) { + int pos = filename.lastIndexOf('/'); + if (pos != -1) { + return filename.substring(pos + 1); + } + return filename; + } + + /** + * parse a schema from the given reader and add result to collection + **/ + public void addSchemaFromReader(NamedReader reader) { + try { + addSchemaFromStringWithFileName(IOUtils.readAll(reader.getReader()), reader.getName()); + } catch (java.io.IOException ex) { + throw new IllegalArgumentException("Failed reading from " + reader.getName() + ": " + ex.getMessage()); + } catch (ParseException ex) { + throw new IllegalArgumentException("Failed parsing schema from " + reader.getName() + ": " + ex.getMessage()); + } + + } + + /** for unit tests */ + public void addSchemaFromFile(String fileName) { + try { + addSchemaFromStringWithFileName(IOUtils.readFile(new File(fileName)), fileName); + } catch (java.io.IOException ex) { + throw new IllegalArgumentException("Could not read file " + fileName + ": " + ex.getMessage()); + } catch (ParseException ex) { + throw new IllegalArgumentException("Failed parsing schema file " + fileName + ": " + ex.getMessage()); + } + } + + /** + * parse a rank profile from the given reader and add to the schema identified by name. + * note: the named schema must have been parsed already. + **/ + public void addRankProfileFile(String schemaName, NamedReader reader) { + try { + ParsedSchema schema = parsedSchemas.get(schemaName); + if (schema == null) { + throw new IllegalArgumentException("No schema named: " + schemaName); + } + var stream = new SimpleCharStream(IOUtils.readAll(reader.getReader())); + var parser = new IntermediateParser(stream, deployLogger, modelProperties); + parser.rankProfile(schema); + } catch (java.io.IOException ex) { + throw new IllegalArgumentException("Failed reading from " + reader.getName() + ": " + ex.getMessage()); + } catch (ParseException ex) { + throw new IllegalArgumentException("Failed parsing rank-profile from " + reader.getName() + ": " + ex.getMessage()); + } + } + + // for unit test + void addRankProfileFile(String schemaName, String fileName) { + try { + var reader = IOUtils.createReader(fileName, "UTF-8"); + addRankProfileFile(schemaName, new NamedReader(fileName, reader)); + } catch (java.io.IOException ex) { + throw new IllegalArgumentException("Could not read file " + fileName + ": " + ex.getMessage()); + } + } + + void resolveInternalConnections() { + var resolver = new InheritanceResolver(parsedSchemas); + resolver.resolveInheritance(); + } +} 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 0b7d0507161..8cd64ef16f7 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 @@ -17,6 +17,7 @@ import java.util.Optional; **/ public class ParsedDocument extends ParsedBlock { private final List<String> inherited = new ArrayList<>(); + private final Map<String, ParsedDocument> resolvedInherits = new HashMap(); private final Map<String, ParsedField> docFields = new HashMap<>(); private final Map<String, ParsedStruct> docStructs = new HashMap<>(); private final Map<String, ParsedAnnotation> docAnnotations = new HashMap<>(); @@ -27,6 +28,7 @@ public class ParsedDocument extends ParsedBlock { List<String> getInherited() { return List.copyOf(inherited); } List<ParsedAnnotation> getAnnotations() { return List.copyOf(docAnnotations.values()); } + List<ParsedDocument> getResolvedInherits() { return List.copyOf(resolvedInherits.values()); } List<ParsedField> getFields() { return List.copyOf(docFields.values()); } List<ParsedStruct> getStructs() { return List.copyOf(docStructs.values()); } @@ -50,6 +52,13 @@ public class ParsedDocument extends ParsedBlock { docAnnotations.put(annName, annotation); } - public String toString() { return "document "+name(); } + public String toString() { return "document " + name(); } + + void resolveInherit(String name, ParsedDocument parsed) { + verifyThat(inherited.contains(name), "resolveInherit for non-inherited name", name); + verifyThat(name.equals(parsed.name()), "resolveInherit name mismatch for", name); + verifyThat(! resolvedInherits.containsKey(name), "double resolveInherit for", name); + resolvedInherits.put(name, parsed); + } } 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 6fce026948d..2011ac24148 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 @@ -39,6 +39,7 @@ class ParsedRankProfile extends ParsedBlock { private String inheritedMatchFeatures = null; private String secondPhaseExpression = null; private Boolean strict = null; + private final List<MutateOperation> mutateOperations = new ArrayList<>(); private final List<String> inherited = new ArrayList<>(); private final Map<String, Boolean> fieldsRankFilter = new HashMap<>(); private final Map<String, Integer> fieldsRankWeight = new HashMap<>(); @@ -66,6 +67,7 @@ class ParsedRankProfile extends ParsedBlock { 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<MutateOperation> getMutateOperations() { return List.copyOf(mutateOperations); } List<String> getInherited() { return List.copyOf(inherited); } Map<String, Boolean> getFieldsWithRankFilter() { return Map.copyOf(fieldsRankFilter); } Map<String, Integer> getFieldsWithRankWeight() { return Map.copyOf(fieldsRankWeight); } @@ -127,7 +129,9 @@ class ParsedRankProfile extends ParsedBlock { functions.put(func.name(), func); } - void addMutateOperation(MutateOperation.Phase phase, String attrName, String operation) {} + void addMutateOperation(MutateOperation.Phase phase, String attrName, String operation) { + mutateOperations.add(new MutateOperation(phase, attrName, operation)); + } void addRankProperty(String key, String value) { verifyThat(! rankProperties.containsKey(key), "already has value for rank property", key); 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 9bdd6a0409d..bf448b31dd2 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 @@ -36,6 +36,7 @@ public class ParsedSchema extends ParsedBlock { private final List<OnnxModel> onnxModels = new ArrayList<>(); private final List<RankingConstant> rankingConstants = new ArrayList<>(); private final List<String> inherited = new ArrayList<>(); + private final Map<String, ParsedSchema> resolvedInherits = new HashMap(); private final Map<String, ParsedAnnotation> extraAnnotations = new HashMap<>(); private final Map<String, ParsedDocumentSummary> docSums = new HashMap<>(); private final Map<String, ParsedField> extraFields = new HashMap<>(); @@ -60,10 +61,11 @@ public class ParsedSchema extends ParsedBlock { List<ParsedField> getFields() { return List.copyOf(extraFields.values()); } List<ParsedFieldSet> getFieldSets() { return List.copyOf(fieldSets.values()); } List<ParsedIndex> getIndexes() { return List.copyOf(extraIndexes.values()); } - List<ParsedRankProfile> getRankProfiles() { return List.copyOf(rankProfiles.values()); } List<ParsedStruct> getStructs() { return List.copyOf(extraStructs.values()); } List<RankingConstant> getRankingConstants() { return List.copyOf(rankingConstants); } List<String> getInherited() { return List.copyOf(inherited); } + Map<String, ParsedRankProfile> getRankProfiles() { return Map.copyOf(rankProfiles); } + List<ParsedSchema> getResolvedInherits() { return List.copyOf(resolvedInherits.values()); } void addAnnotation(ParsedAnnotation annotation) { String annName = annotation.name(); @@ -136,4 +138,12 @@ public class ParsedSchema extends ParsedBlock { "already has stemming", defaultStemming, "cannot also set", value); defaultStemming = value; } + + void resolveInherit(String name, ParsedSchema parsed) { + verifyThat(inherited.contains(name), "resolveInherit for non-inherited name", name); + verifyThat(name.equals(parsed.name()), "resolveInherit name mismatch for", name); + verifyThat(! resolvedInherits.containsKey(name), "double resolveInherit for", name); + resolvedInherits.put(name, parsed); + } + } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java index 4d5280d29eb..9f02c5247ef 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java @@ -104,14 +104,14 @@ class ParsedType { void setCreateIfNonExistent(boolean value) { if (variant != Variant.WSET) { - throw new IllegalArgumentException("CreateIfNonExistent only valid for weightedset, not "+variant); + throw new IllegalArgumentException("CreateIfNonExistent only valid for weightedset, not " + variant); } this.createIfNonExistent = value; } void setRemoveIfZero(boolean value) { if (variant != Variant.WSET) { - throw new IllegalArgumentException("RemoveIfZero only valid for weightedset, not "+variant); + throw new IllegalArgumentException("RemoveIfZero only valid for weightedset, not " + variant); } this.removeIfZero = value; } @@ -119,7 +119,7 @@ class ParsedType { void setVariant(Variant value) { if (variant == value) return; // already OK if (variant != Variant.UNKNOWN) { - throw new IllegalArgumentException("setVariant("+value+") only valid for UNKNOWN, not: "+variant); + throw new IllegalArgumentException("setVariant(" + value + ") only valid for UNKNOWN, not: " + variant); } // maybe even more checking would be useful this.variant = value; diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateCollectionTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateCollectionTestCase.java new file mode 100644 index 00000000000..1ee7ae4937a --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/parser/IntermediateCollectionTestCase.java @@ -0,0 +1,188 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.parser; + +import com.yahoo.io.IOUtils; +import com.yahoo.io.reader.NamedReader; +import static com.yahoo.config.model.test.TestUtil.joinLines; + +import java.nio.charset.StandardCharsets; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThrows; + +/** + * @author arnej + */ +public class IntermediateCollectionTestCase { + + @Test + public void can_add_minimal_schema() throws Exception { + String input = joinLines + ("schema foo {", + " document bar {", + " }", + "}"); + var collection = new IntermediateCollection(); + ParsedSchema schema = collection.addSchemaFromString(input); + assertEquals("foo", schema.name()); + assertTrue(schema.hasDocument()); + assertEquals("bar", schema.getDocument().name()); + } + + @Test + public void can_add_schema_files() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromFile("src/test/derived/deriver/child.sd"); + collection.addSchemaFromFile("src/test/derived/deriver/grandparent.sd"); + collection.addSchemaFromFile("src/test/derived/deriver/parent.sd"); + var schemes = collection.getParsedSchemas(); + assertEquals(schemes.size(), 3); + var schema = schemes.get("child"); + assertTrue(schema != null); + assertEquals(schema.name(), "child"); + schema = schemes.get("parent"); + assertTrue(schema != null); + assertEquals(schema.name(), "parent"); + schema = schemes.get("grandparent"); + assertTrue(schema != null); + assertEquals(schema.name(), "grandparent"); + } + + NamedReader readerOf(String fileName) throws Exception { + File f = new File(fileName); + FileReader fr = new FileReader(f, StandardCharsets.UTF_8); + BufferedReader br = new BufferedReader(fr); + return new NamedReader(fileName, br); + } + + @Test + public void can_add_schemas() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromReader(readerOf("src/test/derived/deriver/child.sd")); + collection.addSchemaFromReader(readerOf("src/test/derived/deriver/grandparent.sd")); + collection.addSchemaFromReader(readerOf("src/test/derived/deriver/parent.sd")); + var schemes = collection.getParsedSchemas(); + assertEquals(schemes.size(), 3); + var schema = schemes.get("child"); + assertTrue(schema != null); + assertEquals(schema.name(), "child"); + schema = schemes.get("parent"); + assertTrue(schema != null); + assertEquals(schema.name(), "parent"); + schema = schemes.get("grandparent"); + assertTrue(schema != null); + assertEquals(schema.name(), "grandparent"); + } + + @Test + public void can_add_extra_rank_profiles() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromFile("src/test/derived/rankprofilemodularity/test.sd"); + collection.addRankProfileFile("test", "src/test/derived/rankprofilemodularity/test/outside_schema1.profile"); + collection.addRankProfileFile("test", readerOf("src/test/derived/rankprofilemodularity/test/outside_schema2.profile")); + var schemes = collection.getParsedSchemas(); + assertEquals(schemes.size(), 1); + var schema = schemes.get("test"); + assertTrue(schema != null); + assertEquals(schema.name(), "test"); + var rankProfiles = schema.getRankProfiles(); + assertEquals(rankProfiles.size(), 7); + var outside = rankProfiles.get("outside_schema1"); + assertTrue(outside != null); + assertEquals(outside.name(), "outside_schema1"); + var functions = outside.getFunctions(); + assertEquals(functions.size(), 1); + assertEquals(functions.get(0).name(), "fo1"); + outside = rankProfiles.get("outside_schema2"); + assertTrue(outside != null); + assertEquals(outside.name(), "outside_schema2"); + functions = outside.getFunctions(); + assertEquals(functions.size(), 1); + assertEquals(functions.get(0).name(), "fo2"); + } + + @Test + public void name_mismatch_throws() throws Exception { + var collection = new IntermediateCollection(); + var ex = assertThrows(IllegalArgumentException.class, () -> + collection.addSchemaFromReader(readerOf("src/test/cfg/application/sdfilenametest/schemas/notmusic.sd"))); + assertEquals("The file containing schema 'music' must be named 'music.sd', was 'notmusic.sd'", + ex.getMessage()); + } + + @Test + public void bad_parse_throws() throws Exception { + var collection = new IntermediateCollection(); + var ex = assertThrows(IllegalArgumentException.class, () -> + collection.addSchemaFromFile("src/test/examples/structoutsideofdocument.sd")); + assertTrue(ex.getMessage().startsWith("Failed parsing schema file src/test/examples/structoutsideofdocument.sd: ")); + ex = assertThrows(IllegalArgumentException.class, () -> + collection.addSchemaFromReader(readerOf("src/test/examples/structoutsideofdocument.sd"))); + assertTrue(ex.getMessage().startsWith("Failed parsing schema from src/test/examples/structoutsideofdocument.sd: ")); + collection.addSchemaFromFile("src/test/derived/rankprofilemodularity/test.sd"); + collection.addRankProfileFile("test", "src/test/derived/rankprofilemodularity/test/outside_schema1.profile"); + ex = assertThrows(IllegalArgumentException.class, () -> + collection.addRankProfileFile("test", "src/test/examples/structoutsideofdocument.sd")); + assertTrue(ex.getMessage().startsWith("Failed parsing rank-profile from src/test/examples/structoutsideofdocument.sd: ")); + } + + @Test + public void can_resolve_document_inheritance() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromFile("src/test/derived/deriver/child.sd"); + collection.addSchemaFromFile("src/test/derived/deriver/grandparent.sd"); + collection.addSchemaFromFile("src/test/derived/deriver/parent.sd"); + collection.resolveInternalConnections(); + var schemes = collection.getParsedSchemas(); + assertEquals(schemes.size(), 3); + var childDoc = schemes.get("child").getDocument(); + var inherits = childDoc.getResolvedInherits(); + assertEquals(inherits.size(), 1); + var parentDoc = inherits.get(0); + assertEquals(parentDoc.name(), "parent"); + inherits = parentDoc.getResolvedInherits(); + assertEquals(inherits.size(), 1); + assertEquals(inherits.get(0).name(), "grandparent"); + } + + @Test + public void can_detect_schema_inheritance_cycles() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromString("schema foo inherits bar {}"); + collection.addSchemaFromString("schema bar inherits qux {}"); + collection.addSchemaFromString("schema qux inherits foo {}"); + assertEquals(collection.getParsedSchemas().size(), 3); + var ex = assertThrows(IllegalArgumentException.class, () -> + collection.resolveInternalConnections()); + assertTrue(ex.getMessage().startsWith("Inheritance cycle for schemas: ")); + } + + @Test + public void can_detect_document_inheritance_cycles() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromString("schema foo { document foo inherits bar {} }"); + collection.addSchemaFromString("schema bar { document bar inherits qux {} }"); + collection.addSchemaFromString("schema qux { document qux inherits foo {} }"); + assertEquals(collection.getParsedSchemas().size(), 3); + var ex = assertThrows(IllegalArgumentException.class, () -> + collection.resolveInternalConnections()); + assertTrue(ex.getMessage().startsWith("Inheritance cycle for documents: ")); + } + + @Test + public void can_detect_missing_doc() throws Exception { + var collection = new IntermediateCollection(); + collection.addSchemaFromString("schema foo { document foo inherits bar {} }"); + collection.addSchemaFromString("schema qux { document qux inherits foo {} }"); + assertEquals(collection.getParsedSchemas().size(), 2); + var ex = assertThrows(IllegalArgumentException.class, () -> + collection.resolveInternalConnections()); + assertEquals("document foo inherits from unavailable document bar", ex.getMessage()); + } + +} diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java index 9fa0a515abc..f022ed11f3d 100644 --- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java +++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java @@ -17,6 +17,7 @@ import com.yahoo.vespa.config.RawConfig; import com.yahoo.vespa.config.TimingValues; import com.yahoo.vespa.config.protocol.JRTServerConfigRequest; +import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -68,7 +69,7 @@ class RpcConfigSourceClient implements ConfigSourceClient, Runnable { this.memoryCache = new MemoryCache(); this.delayedResponses = new DelayedResponses(); checkConfigSources(); - nextConfigFuture = nextConfigScheduler.scheduleAtFixedRate(this, 0, 10*1000/SystemTimer.detectHz(), MILLISECONDS); + nextConfigFuture = nextConfigScheduler.scheduleAtFixedRate(this, 0, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(10)).toMillis(), MILLISECONDS); this.requesters = new JrtConfigRequesters(); DelayedResponseHandler command = new DelayedResponseHandler(delayedResponses, memoryCache, responseHandler); this.delayedResponsesFuture = delayedResponsesScheduler.scheduleAtFixedRate(command, 5, 1, SECONDS); diff --git a/config/src/tests/subscriber/subscriber.cpp b/config/src/tests/subscriber/subscriber.cpp index d7320bb6a2f..0bc5cf0699e 100644 --- a/config/src/tests/subscriber/subscriber.cpp +++ b/config/src/tests/subscriber/subscriber.cpp @@ -77,6 +77,7 @@ namespace { MyManager() : idCounter(0), numCancel(0) { } + ~MyManager() override; ConfigSubscription::SP subscribe(const ConfigKey & key, vespalib::duration timeout) override { (void) timeout; @@ -112,6 +113,8 @@ namespace { }; + MyManager::~MyManager() = default; + class APIFixture : public IConfigContext { public: diff --git a/config/src/tests/trace/trace.cpp b/config/src/tests/trace/trace.cpp index b19a0425c5a..4370e1a91d6 100644 --- a/config/src/tests/trace/trace.cpp +++ b/config/src/tests/trace/trace.cpp @@ -12,10 +12,13 @@ using namespace vespalib::slime; struct FixedClock : public Clock { FixedClock() : _currentTime() { } + ~FixedClock() override; vespalib::system_time _currentTime; vespalib::system_time currentTime() const override { return _currentTime; } }; +FixedClock::~FixedClock() = default; + TEST("that trace can be serialized and deserialized") { Trace trace(4); trace.trace(4, "foo"); diff --git a/config/src/vespa/config/subscription/sourcespec.cpp b/config/src/vespa/config/subscription/sourcespec.cpp index 15f45434056..928e2994b02 100644 --- a/config/src/vespa/config/subscription/sourcespec.cpp +++ b/config/src/vespa/config/subscription/sourcespec.cpp @@ -63,6 +63,8 @@ DirSpec::DirSpec(const vespalib::string & dirName) { } +DirSpec::~DirSpec() = default; + std::unique_ptr<SourceFactory> DirSpec::createSourceFactory(const TimingValues & ) const { diff --git a/config/src/vespa/config/subscription/sourcespec.h b/config/src/vespa/config/subscription/sourcespec.h index e2bdd1c61ee..3dd735b30a7 100644 --- a/config/src/vespa/config/subscription/sourcespec.h +++ b/config/src/vespa/config/subscription/sourcespec.h @@ -108,6 +108,7 @@ public: * @param dirName Directory to serve config from. */ DirSpec(const vespalib::string & dirName); + ~DirSpec() override; /** * Get directory handled by this spec. @@ -237,4 +238,3 @@ private: }; } - diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java index 2a6b0a2768d..87268f88363 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java @@ -682,7 +682,7 @@ public class InternalStepRunner implements StepRunner { logger.log(INFO, "The test package must either contain basic HTTP tests under 'tests/<suite-name>/', " + "or a Java test bundle under 'components/' with at least one test with the annotation " + "for this suite. See docs.vespa.ai/en/testing.html for details."); - return Optional.of(testFailure); + return Optional.of(running); // Let no tests pass until all apps meet this requirement. case SUCCESS: logger.log("Tests completed successfully."); controller.jobController().updateTestReport(id); diff --git a/document/src/vespa/document/base/field.cpp b/document/src/vespa/document/base/field.cpp index 86b1d93eacf..d19e9c372eb 100644 --- a/document/src/vespa/document/base/field.cpp +++ b/document/src/vespa/document/base/field.cpp @@ -48,6 +48,8 @@ Field::Field(vespalib::stringref name, const DataType& dataType) _fieldId(calculateIdV7()) { } +Field::~Field() = default; + FieldValue::UP Field::createValue() const { return _dataType->createFieldValue(); diff --git a/document/src/vespa/document/base/field.h b/document/src/vespa/document/base/field.h index 378dc16cda6..6a2dadf8cd6 100644 --- a/document/src/vespa/document/base/field.h +++ b/document/src/vespa/document/base/field.h @@ -86,6 +86,8 @@ public: */ Field(vespalib::stringref name, const DataType &dataType); + ~Field() override; + std::unique_ptr<FieldValue> createValue() const; // Note that only id is checked for equality. diff --git a/documentapi/src/tests/routablefactory/routablefactory.cpp b/documentapi/src/tests/routablefactory/routablefactory.cpp index a1b0050efd8..be8c8ad0c39 100644 --- a/documentapi/src/tests/routablefactory/routablefactory.cpp +++ b/documentapi/src/tests/routablefactory/routablefactory.cpp @@ -59,8 +59,12 @@ protected: (void)buf; return true; } +public: + ~MyMessageFactory() override; }; +MyMessageFactory::~MyMessageFactory() = default; + class MyReplyFactory : public RoutableFactories60::DocumentReplyFactory { protected: DocumentReply::UP doDecode(document::ByteBuffer &buf) const override { @@ -73,8 +77,12 @@ protected: (void)buf; return true; } +public: + ~MyReplyFactory() override; }; +MyReplyFactory::~MyReplyFactory() = default; + /////////////////////////////////////////////////////////////////////////////// // // Setup diff --git a/eval/src/tests/eval/compile_cache/compile_cache_test.cpp b/eval/src/tests/eval/compile_cache/compile_cache_test.cpp index 6565ece735e..c9d56de897c 100644 --- a/eval/src/tests/eval/compile_cache/compile_cache_test.cpp +++ b/eval/src/tests/eval/compile_cache/compile_cache_test.cpp @@ -79,6 +79,7 @@ TEST("require that different strings give different function keys") { struct CheckKeys : test::EvalSpec::EvalTest { bool failed = false; std::set<vespalib::string> seen_keys; + ~CheckKeys() override; bool check_key(const vespalib::string &key) { bool seen = (seen_keys.count(key) > 0); seen_keys.insert(key); @@ -104,6 +105,8 @@ struct CheckKeys : test::EvalSpec::EvalTest { double) override {} }; +CheckKeys::~CheckKeys() = default; + TEST_FF("require that all conformance expressions have different function keys", CheckKeys(), test::EvalSpec()) { @@ -245,6 +248,8 @@ struct CompileCheck : test::EvalSpec::EvalTest { double expect; Entry(CompileCache::Token::UP fun_in, const std::vector<double> ¶ms_in, double expect_in) : fun(std::move(fun_in)), params(params_in), expect(expect_in) {} + Entry(Entry&&) noexcept = default; + ~Entry(); }; std::vector<Entry> list; void next_expression(const std::vector<vespalib::string> &, @@ -273,6 +278,8 @@ struct CompileCheck : test::EvalSpec::EvalTest { } }; +CompileCheck::Entry::~Entry() = default; + TEST_F("compile sequentially, then run all conformance tests", test::EvalSpec()) { f1.add_all_cases(); for (size_t i = 0; i < 2; ++i) { diff --git a/eval/src/tests/eval/compiled_function/compiled_function_test.cpp b/eval/src/tests/eval/compiled_function/compiled_function_test.cpp index dc7fde7f435..45e0c6d08fc 100644 --- a/eval/src/tests/eval/compiled_function/compiled_function_test.cpp +++ b/eval/src/tests/eval/compiled_function/compiled_function_test.cpp @@ -78,6 +78,8 @@ struct MyEvalTest : test::EvalSpec::EvalTest { size_t fail_cnt = 0; bool print_pass = false; bool print_fail = false; + + ~MyEvalTest() override; virtual void next_expression(const std::vector<vespalib::string> ¶m_names, const vespalib::string &expression) override { @@ -122,6 +124,8 @@ struct MyEvalTest : test::EvalSpec::EvalTest { } }; +MyEvalTest::~MyEvalTest() = default; + TEST_FF("require that compiled evaluation passes all conformance tests", MyEvalTest(), test::EvalSpec()) { f1.print_fail = true; f2.add_all_cases(); diff --git a/eval/src/tests/eval/function/function_test.cpp b/eval/src/tests/eval/function/function_test.cpp index 793ba98c59b..64f9104d0e1 100644 --- a/eval/src/tests/eval/function/function_test.cpp +++ b/eval/src/tests/eval/function/function_test.cpp @@ -1035,6 +1035,7 @@ TEST("require that tensor cell cast must have valid cell type") { struct CheckExpressions : test::EvalSpec::EvalTest { bool failed = false; size_t seen_cnt = 0; + ~CheckExpressions() override; virtual void next_expression(const std::vector<vespalib::string> ¶m_names, const vespalib::string &expression) override { @@ -1051,6 +1052,8 @@ struct CheckExpressions : test::EvalSpec::EvalTest { double) override {} }; +CheckExpressions::~CheckExpressions() = default; + TEST_FF("require that all conformance test expressions can be parsed", CheckExpressions(), test::EvalSpec()) { diff --git a/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp b/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp index 05136e4f679..7cab1de7bab 100644 --- a/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp +++ b/eval/src/tests/eval/interpreted_function/interpreted_function_test.cpp @@ -26,6 +26,8 @@ struct MyEvalTest : test::EvalSpec::EvalTest { bool print_pass = false; bool print_fail = false; + ~MyEvalTest() override; + virtual void next_expression(const std::vector<vespalib::string> ¶m_names, const vespalib::string &expression) override { @@ -86,6 +88,8 @@ struct MyEvalTest : test::EvalSpec::EvalTest { } }; +MyEvalTest::~MyEvalTest() = default; + TEST_FF("require that interpreted evaluation passes all conformance tests", MyEvalTest(), test::EvalSpec()) { f1.print_fail = true; f2.add_all_cases(); diff --git a/eval/src/tests/eval/value_cache/value_cache_test.cpp b/eval/src/tests/eval/value_cache/value_cache_test.cpp index 361931c9dbe..3f6a134c862 100644 --- a/eval/src/tests/eval/value_cache/value_cache_test.cpp +++ b/eval/src/tests/eval/value_cache/value_cache_test.cpp @@ -21,8 +21,11 @@ struct MyFactory : ConstantValueFactory { ++create_cnt; return std::make_unique<MyValue>(double(atoi(path.c_str()))); } + ~MyFactory(); }; +MyFactory::~MyFactory() = default; + TEST_FF("require that values can be created", MyFactory(), ConstantValueCache(f1)) { ConstantValue::UP res = f2.create("1", "type"); EXPECT_TRUE(res->type().is_double()); diff --git a/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp b/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp index 51a139958dd..dae47391d54 100644 --- a/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp +++ b/eval/src/tests/instruction/generic_rename/generic_rename_test.cpp @@ -33,6 +33,12 @@ const std::vector<GenSpec> rename_layouts = { struct FromTo { std::vector<vespalib::string> from; std::vector<vespalib::string> to; + + FromTo(const std::vector<vespalib::string>& from_in, const std::vector<vespalib::string>& to_in) + : from(from_in), + to(to_in) + { + } }; std::vector<FromTo> rename_from_to = { diff --git a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp index 786301a252f..065c9426452 100644 --- a/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp +++ b/eval/src/tests/tensor/instruction_benchmark/instruction_benchmark.cpp @@ -270,7 +270,11 @@ struct BenchmarkResult { double star_rating; BenchmarkResult(const vespalib::string &desc_in, size_t num_values) : desc(desc_in), ref_time(std::nullopt), relative_perf(num_values, 0.0) {} + BenchmarkResult(const BenchmarkResult&); + BenchmarkResult(BenchmarkResult&&) noexcept = default; ~BenchmarkResult(); + BenchmarkResult& operator=(const BenchmarkResult&); + BenchmarkResult& operator=(BenchmarkResult&&) noexcept; void sample(size_t order, double time) { relative_perf[order] = time; if (order == 0) { @@ -305,8 +309,15 @@ struct BenchmarkResult { fprintf(stderr, "| %s\n", desc.c_str()); } }; + +BenchmarkResult::BenchmarkResult(const BenchmarkResult&) = default; + BenchmarkResult::~BenchmarkResult() = default; +BenchmarkResult& BenchmarkResult::operator=(const BenchmarkResult&) = default; + +BenchmarkResult& BenchmarkResult::operator=(BenchmarkResult&&) noexcept = default; + std::vector<BenchmarkResult> benchmark_results; //----------------------------------------------------------------------------- diff --git a/eval/src/vespa/eval/eval/fast_value.hpp b/eval/src/vespa/eval/eval/fast_value.hpp index a0a96bc4497..a40314430c7 100644 --- a/eval/src/vespa/eval/eval/fast_value.hpp +++ b/eval/src/vespa/eval/eval/fast_value.hpp @@ -149,7 +149,7 @@ inline bool is_fast(const Value::Index &index) { return (std::type_index(typeid(index)) == std::type_index(typeid(FastValueIndex))); } -inline bool are_fast(const Value::Index &a, const Value::Index &b) { +__attribute__((always_inline)) inline bool are_fast(const Value::Index &a, const Value::Index &b) { return (is_fast(a) && is_fast(b)); } diff --git a/eval/src/vespa/eval/eval/nested_loop.h b/eval/src/vespa/eval/eval/nested_loop.h index 67b8532b0ee..92e84f5c052 100644 --- a/eval/src/vespa/eval/eval/nested_loop.h +++ b/eval/src/vespa/eval/eval/nested_loop.h @@ -2,6 +2,7 @@ #pragma once +#include <cstddef> #include <vector> namespace vespalib::eval { diff --git a/eval/src/vespa/eval/eval/test/eval_spec.cpp b/eval/src/vespa/eval/eval/test/eval_spec.cpp index 415404ffa50..02e9c34a75e 100644 --- a/eval/src/vespa/eval/eval/test/eval_spec.cpp +++ b/eval/src/vespa/eval/eval/test/eval_spec.cpp @@ -29,6 +29,8 @@ double byte(const vespalib::string &bits) { constexpr double my_nan = std::numeric_limits<double>::quiet_NaN(); constexpr double my_inf = std::numeric_limits<double>::infinity(); +EvalSpec::Expression::~Expression() = default; + EvalSpec::Expression &EvalSpec::Expression::add_case(std::initializer_list<double> param_values, double expected_result) { assert(param_values.size() == param_names.size()); diff --git a/eval/src/vespa/eval/eval/test/eval_spec.h b/eval/src/vespa/eval/eval/test/eval_spec.h index 57415a0d984..aaf3481241a 100644 --- a/eval/src/vespa/eval/eval/test/eval_spec.h +++ b/eval/src/vespa/eval/eval/test/eval_spec.h @@ -32,6 +32,7 @@ private: std::vector<Case> cases; Expression(std::initializer_list<vespalib::string> param_names_in, vespalib::string expression_in) : param_names(param_names_in), expression(expression_in) {} + ~Expression(); Expression &add_case(std::initializer_list<double> param_values, double expected_result); Expression &add_cases(std::initializer_list<double> a_values, fun_1_ref fun); diff --git a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp index d6a7f54a78e..9af473f1f94 100644 --- a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp +++ b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.cpp @@ -68,6 +68,8 @@ void decode_json(const vespalib::string &path, Slime &slime) { } // namespace vespalib::eval::<unnamed> +ConstantTensorLoader::~ConstantTensorLoader() = default; + ConstantValue::UP ConstantTensorLoader::create(const vespalib::string &path, const vespalib::string &type) const { diff --git a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h index 9ecd9b8f2cf..c90ff611934 100644 --- a/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h +++ b/eval/src/vespa/eval/eval/value_cache/constant_tensor_loader.h @@ -19,6 +19,7 @@ private: const ValueBuilderFactory &_factory; public: ConstantTensorLoader(const ValueBuilderFactory &factory) : _factory(factory) {} + ~ConstantTensorLoader(); ConstantValue::UP create(const vespalib::string &path, const vespalib::string &type) const override; }; diff --git a/eval/src/vespa/eval/eval/value_cache/constant_value_cache.cpp b/eval/src/vespa/eval/eval/value_cache/constant_value_cache.cpp index 87fd983fbc7..c03ef94b2ec 100644 --- a/eval/src/vespa/eval/eval/value_cache/constant_value_cache.cpp +++ b/eval/src/vespa/eval/eval/value_cache/constant_value_cache.cpp @@ -20,6 +20,8 @@ ConstantValueCache::ConstantValueCache(const ConstantValueFactory &factory) { } +ConstantValueCache::~ConstantValueCache() = default; + ConstantValue::UP ConstantValueCache::create(const vespalib::string &path, const vespalib::string &type) const { diff --git a/eval/src/vespa/eval/eval/value_cache/constant_value_cache.h b/eval/src/vespa/eval/eval/value_cache/constant_value_cache.h index 93fc9157c3b..6ba83027d12 100644 --- a/eval/src/vespa/eval/eval/value_cache/constant_value_cache.h +++ b/eval/src/vespa/eval/eval/value_cache/constant_value_cache.h @@ -50,6 +50,7 @@ private: public: ConstantValueCache(const ConstantValueFactory &factory); ConstantValue::UP create(const vespalib::string &path, const vespalib::string &type) const override; + ~ConstantValueCache() override; }; } // namespace vespalib::eval diff --git a/fnet/src/tests/frt/parallel_rpc/parallel_rpc_test.cpp b/fnet/src/tests/frt/parallel_rpc/parallel_rpc_test.cpp index b027b80f8ab..74f1dea0c9a 100644 --- a/fnet/src/tests/frt/parallel_rpc/parallel_rpc_test.cpp +++ b/fnet/src/tests/frt/parallel_rpc/parallel_rpc_test.cpp @@ -42,6 +42,7 @@ struct Server : Rpc { init_rpc(); start(); } + ~Server() override; void init_rpc() { FRT_ReflectionBuilder rb(&orb); rb.DefineMethod("inc", "l", "l", FRT_METHOD(Server::rpc_inc), this); @@ -56,14 +57,19 @@ struct Server : Rpc { } }; +Server::~Server() = default; + struct Client : Rpc { uint32_t port; Client(CryptoEngine::SP crypto, size_t num_threads, const Server &server, bool drop_empty = false) : Rpc(std::move(crypto), num_threads, drop_empty), port(server.port) { start(); } + ~Client() override; FRT_Target *connect() { return Rpc::connect(port); } }; +Client::~Client() = default; + struct Result { std::vector<double> req_per_sec; explicit Result(size_t num_threads) : req_per_sec(num_threads, 0.0) {} diff --git a/fnet/src/tests/frt/parallel_rpc/tls_rpc_bench.cpp b/fnet/src/tests/frt/parallel_rpc/tls_rpc_bench.cpp index 1ab6afac59b..417dba8d803 100644 --- a/fnet/src/tests/frt/parallel_rpc/tls_rpc_bench.cpp +++ b/fnet/src/tests/frt/parallel_rpc/tls_rpc_bench.cpp @@ -35,7 +35,7 @@ struct Fixture : FRT_Invokable { FRT_Target *connect() { return orb.GetTarget(orb.GetListenPort()); } - ~Fixture() = default; + ~Fixture(); void init_rpc() { FRT_ReflectionBuilder rb(&orb); rb.DefineMethod("inc", "l", "l", FRT_METHOD(Fixture::rpc_inc), this); @@ -50,6 +50,8 @@ struct Fixture : FRT_Invokable { } }; +Fixture::~Fixture() = default; + struct DurationCmp { bool operator()(const TimeTracer::Record &a, const TimeTracer::Record &b) { return ((a.stop - a.start) < (b.stop - b.start)); diff --git a/juniper/src/vespa/juniper/CMakeLists.txt b/juniper/src/vespa/juniper/CMakeLists.txt index 4b4ae30a7ac..5420aa203ea 100644 --- a/juniper/src/vespa/juniper/CMakeLists.txt +++ b/juniper/src/vespa/juniper/CMakeLists.txt @@ -2,6 +2,7 @@ vespa_add_library(juniper SOURCES Matcher.cpp + appender.cpp sumdesc.cpp mcand.cpp keyocc.cpp diff --git a/juniper/src/vespa/juniper/appender.cpp b/juniper/src/vespa/juniper/appender.cpp new file mode 100644 index 00000000000..4d55f62a27a --- /dev/null +++ b/juniper/src/vespa/juniper/appender.cpp @@ -0,0 +1,129 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "appender.h" +#include "juniperdebug.h" +#define _NEED_SUMMARY_CONFIG_IMPL +#include "SummaryConfig.h" + +namespace juniper { + +void +Appender::append(std::vector<char> & s, char c) +{ + JD_INVAR(JD_INPUT, c != 0, return,\ + LOG(warning, "Document source contained 0-bytes")); + // eliminate separators: + if (_sumconf->separator(c)) { + return; + } + + // eliminate multiple space characters + if (!_preserve_white_space) { + if (c > 0 && isspace(c)) { + if (_last_was_space) { + return; + } else { + _last_was_space = true; + } + c = ' '; // Never output newline or tab + } else { + _last_was_space = false; + } + } + + bool handled_as_markup; + if (_escape_markup) { + handled_as_markup = true; + switch (c) { + case '<': + s.push_back('&'); + s.push_back('l'); + s.push_back('t'); + s.push_back(';'); + break; + case '>': + s.push_back('&'); + s.push_back('g'); + s.push_back('t'); + s.push_back(';'); + break; + case '"': + s.push_back('&'); + s.push_back('q'); + s.push_back('u'); + s.push_back('o'); + s.push_back('t'); + s.push_back(';'); + break; + case '&': + s.push_back('&'); + s.push_back('a'); + s.push_back('m'); + s.push_back('p'); + s.push_back(';'); + break; + case '\'': + s.push_back('&'); + s.push_back('#'); + s.push_back('3'); + s.push_back('9'); + s.push_back(';'); + break; + default: + handled_as_markup = false; + break; + } + if (handled_as_markup) { + _char_len++; + } + } else { + handled_as_markup = false; + } + + if (!handled_as_markup) { + s.push_back(c); + /** If at start of an UTF8 character (both highest bits or none of them set) + * another char is accumulated.. + */ + if (!(c & 0x80) || (c & 0x40) ) { + _char_len++; + } + } +} + +Appender::Appender(const SummaryConfig *sumconf) + : _sumconf(sumconf), + _escape_markup(false), + _preserve_white_space(false), + _last_was_space(false), + _char_len(0) +{ + ConfigFlag esc_conf = _sumconf->escape_markup(); + + switch (esc_conf) { + case CF_OFF: + _escape_markup = false; + break; + case CF_ON: + _escape_markup = true; + break; + case CF_AUTO: + _escape_markup = (_sumconf->highlight_on()[0] == '<' || + _sumconf->highlight_off()[0] == '<' || + _sumconf->dots()[0] == '<'); + break; + } + + if (_sumconf->preserve_white_space() == CF_ON) { + _preserve_white_space = true; + } +} + +void +Appender::append(std::vector<char>& s, const char* ds, int length) { + for (int i = 0; i < length; i++) { + append(s, ds[i]); + } +} + +} diff --git a/juniper/src/vespa/juniper/appender.h b/juniper/src/vespa/juniper/appender.h index ade199e00c2..760fd18feca 100644 --- a/juniper/src/vespa/juniper/appender.h +++ b/juniper/src/vespa/juniper/appender.h @@ -2,6 +2,10 @@ #pragma once #include <vespa/vespalib/util/hdr_abort.h> +#include <cstddef> +#include <vector> + +class SummaryConfig; namespace juniper { @@ -14,124 +18,14 @@ private: bool _last_was_space; size_t _char_len; - inline void append(std::vector<char> & s, char c) { - JD_INVAR(JD_INPUT, c != 0, return,\ - LOG(warning, "Document source contained 0-bytes")); - // eliminate separators: - if (_sumconf->separator(c)) { - return; - } - - // eliminate multiple space characters - if (!_preserve_white_space) { - if (c > 0 && isspace(c)) { - if (_last_was_space) { - return; - } else { - _last_was_space = true; - } - c = ' '; // Never output newline or tab - } else { - _last_was_space = false; - } - } - - bool handled_as_markup; - if (_escape_markup) { - handled_as_markup = true; - switch (c) { - case '<': - s.push_back('&'); - s.push_back('l'); - s.push_back('t'); - s.push_back(';'); - break; - case '>': - s.push_back('&'); - s.push_back('g'); - s.push_back('t'); - s.push_back(';'); - break; - case '"': - s.push_back('&'); - s.push_back('q'); - s.push_back('u'); - s.push_back('o'); - s.push_back('t'); - s.push_back(';'); - break; - case '&': - s.push_back('&'); - s.push_back('a'); - s.push_back('m'); - s.push_back('p'); - s.push_back(';'); - break; - case '\'': - s.push_back('&'); - s.push_back('#'); - s.push_back('3'); - s.push_back('9'); - s.push_back(';'); - break; - default: - handled_as_markup = false; - break; - } - if (handled_as_markup) { - _char_len++; - } - } else { - handled_as_markup = false; - } - - if (!handled_as_markup) { - s.push_back(c); - /** If at start of an UTF8 character (both highest bits or none of them set) - * another char is accumulated.. - */ - if (!(c & 0x80) || (c & 0x40) ) { - _char_len++; - } - } - } + void append(std::vector<char> & s, char c); public: - Appender(const SummaryConfig *sumconf) - : _sumconf(sumconf), - _escape_markup(false), - _preserve_white_space(false), - _last_was_space(false), - _char_len(0) - { - ConfigFlag esc_conf = _sumconf->escape_markup(); - - switch (esc_conf) { - case CF_OFF: - _escape_markup = false; - break; - case CF_ON: - _escape_markup = true; - break; - case CF_AUTO: - _escape_markup = (_sumconf->highlight_on()[0] == '<' || - _sumconf->highlight_off()[0] == '<' || - _sumconf->dots()[0] == '<'); - break; - } - - if (_sumconf->preserve_white_space() == CF_ON) { - _preserve_white_space = true; - } - } + Appender(const SummaryConfig *sumconf); size_t charLen() const { return _char_len; } - void append(std::vector<char>& s, const char* ds, int length) { - for (int i = 0; i < length; i++) { - append(s, ds[i]); - } - } + void append(std::vector<char>& s, const char* ds, int length); }; } // end namespace juniper diff --git a/messagebus/src/main/java/com/yahoo/messagebus/MessageBus.java b/messagebus/src/main/java/com/yahoo/messagebus/MessageBus.java index 8611801b9a9..c3279d994c9 100644 --- a/messagebus/src/main/java/com/yahoo/messagebus/MessageBus.java +++ b/messagebus/src/main/java/com/yahoo/messagebus/MessageBus.java @@ -2,6 +2,8 @@ package com.yahoo.messagebus; import com.yahoo.concurrent.SystemTimer; + +import java.time.Duration; import java.util.logging.Level; import com.yahoo.messagebus.network.Network; import com.yahoo.messagebus.network.NetworkMultiplexer; @@ -88,6 +90,7 @@ public class MessageBus implements ConfigHandler, NetworkOwner, MessageHandler, } private void sendBlockedMessages() { + long timeout = SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(10)).toMillis(); while (! destroyed.get()) { for (SendBlockedMessages sender : blockedSenders.keySet()) { if (!sender.trySend()) { @@ -95,8 +98,7 @@ public class MessageBus implements ConfigHandler, NetworkOwner, MessageHandler, } } try { - - Thread.sleep(10); + Thread.sleep(timeout); } catch (InterruptedException e) { return; } diff --git a/messagebus/src/main/java/com/yahoo/messagebus/Messenger.java b/messagebus/src/main/java/com/yahoo/messagebus/Messenger.java index f2ebbbe76cb..871f53396b4 100755 --- a/messagebus/src/main/java/com/yahoo/messagebus/Messenger.java +++ b/messagebus/src/main/java/com/yahoo/messagebus/Messenger.java @@ -1,6 +1,9 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.messagebus; +import com.yahoo.concurrent.SystemTimer; + +import java.time.Duration; import java.util.logging.Level; import java.util.ArrayDeque; @@ -147,12 +150,17 @@ public class Messenger implements Runnable { @Override public void run() { + long timeoutMS = SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(100)).toMillis(); while (true) { Task task = null; synchronized (this) { if (queue.isEmpty()) { try { - wait(10); + if (children.isEmpty()) { + wait(); + } else { + wait(timeoutMS); + } } catch (final InterruptedException e) { continue; } @@ -173,8 +181,7 @@ public class Messenger implements Runnable { try { task.destroy(); } catch (final Exception e) { - log.warning("An exception was thrown while destroying " + task.getClass().getName() + ": " + - e.toString()); + log.warning("An exception was thrown while destroying " + task.getClass().getName() + ": " + e); log.warning("Someone, somewhere might have to wait indefinitely for something."); } } diff --git a/messagebus/src/tests/routing/routing.cpp b/messagebus/src/tests/routing/routing.cpp index 20468945edd..aefbd8816c6 100644 --- a/messagebus/src/tests/routing/routing.cpp +++ b/messagebus/src/tests/routing/routing.cpp @@ -84,9 +84,12 @@ public: RemoveReplyPolicyFactory(bool selectOnRetry, const std::vector<uint32_t> &consumableErrors, uint32_t idxRemove); + ~RemoveReplyPolicyFactory() override; IRoutingPolicy::UP create(const string ¶m) override; }; +RemoveReplyPolicyFactory::~RemoveReplyPolicyFactory() = default; + RemoveReplyPolicyFactory::RemoveReplyPolicyFactory(bool selectOnRetry, const std::vector<uint32_t> &consumableErrors, uint32_t idxRemove) : @@ -233,6 +236,7 @@ private: public: SetReplyPolicyFactory(bool selectOnRetry, const std::vector<uint32_t> &errors); + ~SetReplyPolicyFactory() override; IRoutingPolicy::UP create(const string ¶m) override; }; @@ -244,6 +248,8 @@ SetReplyPolicyFactory::SetReplyPolicyFactory(bool selectOnRetry, // empty } +SetReplyPolicyFactory::~SetReplyPolicyFactory() = default; + IRoutingPolicy::UP SetReplyPolicyFactory::create(const string ¶m) { @@ -270,12 +276,15 @@ public: class SelectExceptionPolicyFactory : public SimpleProtocol::IPolicyFactory { public: + ~SelectExceptionPolicyFactory() override; IRoutingPolicy::UP create(const string ¶m) override { (void)param; return IRoutingPolicy::UP(new SelectExceptionPolicy()); } }; +SelectExceptionPolicyFactory::~SelectExceptionPolicyFactory() = default; + class MergeExceptionPolicy : public IRoutingPolicy { private: const string _select; @@ -299,11 +308,14 @@ public: class MergeExceptionPolicyFactory : public SimpleProtocol::IPolicyFactory { public: + ~MergeExceptionPolicyFactory() override; IRoutingPolicy::UP create(const string ¶m) override { return IRoutingPolicy::UP(new MergeExceptionPolicy(param)); } }; +MergeExceptionPolicyFactory::~MergeExceptionPolicyFactory() = default; + class MyPolicyFactory : public SimpleProtocol::IPolicyFactory { private: string _selectRoute; diff --git a/messagebus/src/tests/routingcontext/routingcontext.cpp b/messagebus/src/tests/routingcontext/routingcontext.cpp index 737673a73ba..aba50156412 100644 --- a/messagebus/src/tests/routingcontext/routingcontext.cpp +++ b/messagebus/src/tests/routingcontext/routingcontext.cpp @@ -48,9 +48,12 @@ public: CustomPolicyFactory(bool forward, const std::vector<string> &all, const std::vector<string> &matched); + ~CustomPolicyFactory() override; IRoutingPolicy::UP create(const string ¶m) override; }; +CustomPolicyFactory::~CustomPolicyFactory() = default; + class CustomPolicy : public IRoutingPolicy { private: CustomPolicyFactory &_factory; diff --git a/messagebus/src/tests/sendadapter/sendadapter.cpp b/messagebus/src/tests/sendadapter/sendadapter.cpp index b5990521128..0ae957ea340 100644 --- a/messagebus/src/tests/sendadapter/sendadapter.cpp +++ b/messagebus/src/tests/sendadapter/sendadapter.cpp @@ -26,6 +26,7 @@ private: public: typedef std::shared_ptr<TestProtocol> SP; + ~TestProtocol() override; mbus::Blob encode(const vespalib::Version &version, const mbus::Routable &routable) const override { _lastVersion = version; return mbus::SimpleProtocol::encode(version, routable); @@ -37,6 +38,8 @@ public: const vespalib::Version &getLastVersion() { return _lastVersion; } }; +TestProtocol::~TestProtocol() = default; + class TestData { public: Slobrok _slobrok; diff --git a/messagebus/src/vespa/messagebus/routing/routingtablespec.cpp b/messagebus/src/vespa/messagebus/routing/routingtablespec.cpp index 43b1032ce57..328565a3ef7 100644 --- a/messagebus/src/vespa/messagebus/routing/routingtablespec.cpp +++ b/messagebus/src/vespa/messagebus/routing/routingtablespec.cpp @@ -12,8 +12,12 @@ RoutingTableSpec::RoutingTableSpec(const string &protocol) : _routes() { } +RoutingTableSpec::RoutingTableSpec(const RoutingTableSpec&) = default; + RoutingTableSpec::~RoutingTableSpec() {} +RoutingTableSpec& RoutingTableSpec::operator=(const RoutingTableSpec&) = default; + HopSpec RoutingTableSpec::removeHop(uint32_t i) { diff --git a/messagebus/src/vespa/messagebus/routing/routingtablespec.h b/messagebus/src/vespa/messagebus/routing/routingtablespec.h index 5886f82ae81..eb0078d1767 100644 --- a/messagebus/src/vespa/messagebus/routing/routingtablespec.h +++ b/messagebus/src/vespa/messagebus/routing/routingtablespec.h @@ -31,7 +31,11 @@ public: * @param protocol The name of the protocol that this belongs to. */ RoutingTableSpec(const string &protocol); + RoutingTableSpec(const RoutingTableSpec&); + RoutingTableSpec(RoutingTableSpec&&) noexcept = default; ~RoutingTableSpec(); + RoutingTableSpec &operator=(const RoutingTableSpec&); + RoutingTableSpec &operator=(RoutingTableSpec&&) noexcept = default; /** * Returns the name of the protocol that this is the routing table for. diff --git a/messagebus/src/vespa/messagebus/testlib/simpleprotocol.cpp b/messagebus/src/vespa/messagebus/testlib/simpleprotocol.cpp index e90cf0dd7a8..4475851e94a 100644 --- a/messagebus/src/vespa/messagebus/testlib/simpleprotocol.cpp +++ b/messagebus/src/vespa/messagebus/testlib/simpleprotocol.cpp @@ -30,8 +30,11 @@ public: IRoutingPolicy::UP create(const string &) override { return IRoutingPolicy::UP(new AllPolicy()); } + ~AllPolicyFactory() override; }; +AllPolicyFactory::~AllPolicyFactory() = default; + class HashPolicy : public IRoutingPolicy { public: void select(RoutingContext &ctx) override { @@ -53,8 +56,11 @@ public: IRoutingPolicy::UP create(const string &) override { return IRoutingPolicy::UP(new HashPolicy()); } + ~HashPolicyFactory() override; }; +HashPolicyFactory::~HashPolicyFactory() = default; + SimpleProtocol::SimpleProtocol() : _policies() { diff --git a/metrics/src/vespa/metrics/summetric.h b/metrics/src/vespa/metrics/summetric.h index c7d3a91ceed..6d51d22b450 100644 --- a/metrics/src/vespa/metrics/summetric.h +++ b/metrics/src/vespa/metrics/summetric.h @@ -34,6 +34,7 @@ public: StartValue(const AddendMetric &metric) : _startValueChildren(), _startValue(metric.clone(_startValueChildren, CLONE, 0, false)) {} + ~StartValue(); const AddendMetric &getStartValue() const { return static_cast<const AddendMetric &>(*_startValue); } }; diff --git a/metrics/src/vespa/metrics/summetric.hpp b/metrics/src/vespa/metrics/summetric.hpp index 84f9290e1c2..0ff82bc5cdd 100644 --- a/metrics/src/vespa/metrics/summetric.hpp +++ b/metrics/src/vespa/metrics/summetric.hpp @@ -13,6 +13,9 @@ namespace metrics { template<typename AddendMetric> +SumMetric<AddendMetric>::StartValue::~StartValue() = default; + +template<typename AddendMetric> bool SumMetric<AddendMetric>::visit(MetricVisitor& visitor, bool tagAsAutoGenerated) const diff --git a/searchcore/src/tests/proton/common/cachedselect_test.cpp b/searchcore/src/tests/proton/common/cachedselect_test.cpp index 56ae361735e..d197d94fda4 100644 --- a/searchcore/src/tests/proton/common/cachedselect_test.cpp +++ b/searchcore/src/tests/proton/common/cachedselect_test.cpp @@ -196,6 +196,7 @@ public: _gets(0) { } + ~MyIntAv() override; virtual uint32_t get(AttributeVector::DocId doc, largeint_t *v, uint32_t sz) const override @@ -211,6 +212,7 @@ public: } }; +MyIntAv::~MyIntAv() = default; class MyAttributeManager : public MockAttributeManager { diff --git a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp index acd33ab749d..00694b6b78f 100644 --- a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp @@ -148,6 +148,7 @@ struct MoveOperationFeedView : public MyMinimalFeedView { removeIndexFieldsCount(0), onWriteDoneContexts() {} + ~MoveOperationFeedView() override; void putAttributes(SerialNum, search::DocumentIdT, const document::Document &, OnPutDoneType onWriteDone) override { ++putAttributesCount; EXPECT_EQUAL(1, outstandingMoveOps); @@ -192,6 +193,8 @@ struct MoveOperationFeedView : public MyMinimalFeedView { } }; +MoveOperationFeedView::~MoveOperationFeedView() = default; + struct MoveOperationCallback : public IDestructorCallback { std::atomic<int> &outstandingMoveOps; explicit MoveOperationCallback(std::atomic<int> &outstandingMoveOps_) noexcept : outstandingMoveOps(outstandingMoveOps_) { diff --git a/searchcore/src/tests/proton/flushengine/flushengine_test.cpp b/searchcore/src/tests/proton/flushengine/flushengine_test.cpp index 7e4980277e7..506313527eb 100644 --- a/searchcore/src/tests/proton/flushengine/flushengine_test.cpp +++ b/searchcore/src/tests/proton/flushengine/flushengine_test.cpp @@ -254,7 +254,7 @@ protected: public: using SP = std::shared_ptr<SimpleTarget>; - SimpleTarget(Task::UP task, const std::string &name) : + SimpleTarget(Task::UP task, const std::string &name) noexcept : test::DummyFlushTarget(name), _flushedSerial(0), _currentSerial(0), diff --git a/searchcore/src/tests/proton/index/index_writer/CMakeLists.txt b/searchcore/src/tests/proton/index/index_writer/CMakeLists.txt index 7a0090a4f38..4b27f0e9556 100644 --- a/searchcore/src/tests/proton/index/index_writer/CMakeLists.txt +++ b/searchcore/src/tests/proton/index/index_writer/CMakeLists.txt @@ -3,6 +3,7 @@ vespa_add_executable(searchcore_index_writer_test_app TEST SOURCES index_writer_test.cpp DEPENDS + searchcore_test searchcore_index searchcore_pcommon ) diff --git a/searchcore/src/tests/proton/index/index_writer/index_writer_test.cpp b/searchcore/src/tests/proton/index/index_writer/index_writer_test.cpp index 62a691d72e6..75e6b01b46f 100644 --- a/searchcore/src/tests/proton/index/index_writer/index_writer_test.cpp +++ b/searchcore/src/tests/proton/index/index_writer/index_writer_test.cpp @@ -42,6 +42,7 @@ struct MyIndexManager : public test::MockIndexManager wantedLidLimit(0), compactSerial(0) { } + ~MyIndexManager() override; std::string getPut(uint32_t lid) { return toString(puts[lid]); } @@ -72,6 +73,8 @@ struct MyIndexManager : public test::MockIndexManager } }; +MyIndexManager::~MyIndexManager() = default; + struct Fixture { IIndexManager::SP iim; diff --git a/searchcore/src/tests/proton/matching/docid_range_scheduler/docid_range_scheduler_bench.cpp b/searchcore/src/tests/proton/matching/docid_range_scheduler/docid_range_scheduler_bench.cpp index f82377c9188..c85ef7f3446 100644 --- a/searchcore/src/tests/proton/matching/docid_range_scheduler/docid_range_scheduler_bench.cpp +++ b/searchcore/src/tests/proton/matching/docid_range_scheduler/docid_range_scheduler_bench.cpp @@ -204,6 +204,7 @@ struct RangeChecker : vespalib::Rendezvous<std::reference_wrapper<const WorkTrac size_t docid_limit; RangeChecker(size_t num_threads, size_t docid_limit_in) : vespalib::Rendezvous<std::reference_wrapper<const WorkTracker>,bool>(num_threads), docid_limit(docid_limit_in) {} + ~RangeChecker() override; virtual void mingle() override { std::vector<DocidRange> ranges; for (size_t i = 0; i < size(); ++i) { @@ -230,6 +231,8 @@ struct RangeChecker : vespalib::Rendezvous<std::reference_wrapper<const WorkTrac } }; +RangeChecker::~RangeChecker() = default; + const size_t my_docid_limit = 100001; TEST_MT_FFFF("benchmark different combinations of schedulers and work loads", 8, diff --git a/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp b/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp index 34bc9ea13ed..4022bd68c92 100644 --- a/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp +++ b/searchcore/src/tests/proton/proton_config_fetcher/proton_config_fetcher_test.cpp @@ -185,6 +185,7 @@ struct ProtonConfigOwner : public proton::IProtonConfigurer VarHolder<std::shared_ptr<ProtonConfigSnapshot>> _config; ProtonConfigOwner() : _configured(false), _config() { } + ~ProtonConfigOwner() override; bool waitUntilConfigured(vespalib::duration timeout) { vespalib::Timer timer; while (timer.elapsed() < timeout) { @@ -220,6 +221,8 @@ struct ProtonConfigOwner : public proton::IProtonConfigurer } }; +ProtonConfigOwner::~ProtonConfigOwner() = default; + TEST_F("require that bootstrap config manager creats correct key set", BootstrapConfigManager("foo")) { const ConfigKeySet set(f1.createConfigKeySet()); ASSERT_EQUAL(4u, set.size()); diff --git a/searchcore/src/tests/proton/server/health_adapter/health_adapter_test.cpp b/searchcore/src/tests/proton/server/health_adapter/health_adapter_test.cpp index d68b6139835..c779645e7f4 100644 --- a/searchcore/src/tests/proton/server/health_adapter/health_adapter_test.cpp +++ b/searchcore/src/tests/proton/server/health_adapter/health_adapter_test.cpp @@ -7,6 +7,7 @@ using namespace proton; struct MyStatusProducer : public StatusProducer { StatusReport::List list; + ~MyStatusProducer() override; void add(const std::string &comp, StatusReport::State state, const std::string &msg) { @@ -18,6 +19,8 @@ struct MyStatusProducer : public StatusProducer { } }; +MyStatusProducer::~MyStatusProducer() = default; + TEST_FF("require that empty status list passes health check", MyStatusProducer(), HealthAdapter(f1)) { EXPECT_TRUE(f2.getHealth().ok); EXPECT_EQUAL(std::string("All OK"), f2.getHealth().msg); diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp index dd7e6c2ab8d..4d94d2629fe 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp +++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp @@ -121,6 +121,8 @@ Matcher::Matcher(const search::index::Schema &schema, const Properties &props, c } } +Matcher::~Matcher() = default; + MatchingStats Matcher::getStats() { diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.h b/searchcore/src/vespa/searchcore/proton/matching/matcher.h index 62d608279a3..4ef57d69d47 100644 --- a/searchcore/src/vespa/searchcore/proton/matching/matcher.h +++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.h @@ -77,6 +77,7 @@ public: Matcher(const Matcher &) = delete; Matcher &operator=(const Matcher &) = delete; + ~Matcher(); /** * Create a new matcher. The schema represents the current index diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp index 914753d567d..e80d8033751 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp @@ -129,6 +129,7 @@ private: class DaisyChainedFeedToken : public feedtoken::ITransport { public: DaisyChainedFeedToken(FeedToken token) : _token(std::move(token)) {} + ~DaisyChainedFeedToken() override; void send(ResultUP, bool ) override { _token.reset(); } @@ -136,6 +137,8 @@ private: FeedToken _token; }; +DaisyChainedFeedToken::~DaisyChainedFeedToken() = default; + } // namespace void diff --git a/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.cpp b/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.cpp index 969462bac03..0681ff2c40b 100644 --- a/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.cpp @@ -8,6 +8,8 @@ LOG_SETUP(".proton.server.memoryconfigstore"); namespace proton { +ConfigMaps::~ConfigMaps() = default; + MemoryConfigStore::MemoryConfigStore() : _maps(new ConfigMaps) {} MemoryConfigStore::MemoryConfigStore(ConfigMaps::SP maps) : _maps(maps) {} MemoryConfigStore::~MemoryConfigStore() = default; diff --git a/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.h b/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.h index 647ed72da8e..735006389dc 100644 --- a/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.h +++ b/searchcore/src/vespa/searchcore/proton/server/memoryconfigstore.h @@ -13,6 +13,7 @@ struct ConfigMaps { typedef std::shared_ptr<ConfigMaps> SP; std::map<search::SerialNum, DocumentDBConfig::SP> configs; std::set<search::SerialNum> _valid; + ~ConfigMaps(); }; class MemoryConfigStore : public ConfigStore { diff --git a/searchcore/src/vespa/searchcore/proton/server/searchcontext.cpp b/searchcore/src/vespa/searchcore/proton/server/searchcontext.cpp index 4317823f5e2..095a16390ee 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchcontext.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchcontext.cpp @@ -31,4 +31,6 @@ SearchContext::SearchContext(const std::shared_ptr<IndexSearchable> &indexSearch { } +SearchContext::~SearchContext() = default; + } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/server/searchcontext.h b/searchcore/src/vespa/searchcore/proton/server/searchcontext.h index 137e75e68e7..b3a1bf7d447 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchcontext.h +++ b/searchcore/src/vespa/searchcore/proton/server/searchcontext.h @@ -26,6 +26,7 @@ private: public: SearchContext(const std::shared_ptr<IndexSearchable> &indexSearchable, uint32_t docIdLimit); + ~SearchContext() override; }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/test/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/test/CMakeLists.txt index 28f705716bc..abc8c8450e4 100644 --- a/searchcore/src/vespa/searchcore/proton/test/CMakeLists.txt +++ b/searchcore/src/vespa/searchcore/proton/test/CMakeLists.txt @@ -4,9 +4,11 @@ vespa_add_library(searchcore_test STATIC attribute_vectors.cpp bucketfactory.cpp buckethandler.cpp + bucketstatecalculator.cpp clusterstatehandler.cpp documentdb_config_builder.cpp dummy_feed_view.cpp + mock_index_manager.cpp mock_shared_threading_service.cpp userdocumentsbuilder.cpp threading_service_observer.cpp diff --git a/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.cpp b/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.cpp new file mode 100644 index 00000000000..43610405b87 --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.cpp @@ -0,0 +1,9 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "bucketstatecalculator.h" + +namespace proton::test { + +BucketStateCalculator::~BucketStateCalculator() = default; + +} diff --git a/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.h b/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.h index e218058f01e..d8803fd9c27 100644 --- a/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.h +++ b/searchcore/src/vespa/searchcore/proton/test/bucketstatecalculator.h @@ -33,6 +33,7 @@ public: _nodeMaintenance(false) { } + ~BucketStateCalculator() override; BucketStateCalculator &addReady(const document::BucketId &bucket) { _ready.insert(bucket); return *this; diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.cpp b/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.cpp new file mode 100644 index 00000000000..a6d7d1aaf42 --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.cpp @@ -0,0 +1,9 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "mock_index_manager.h" + +namespace proton::test { + +MockIndexManager::~MockIndexManager() = default; + +} diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.h b/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.h index bf76dc3d59b..134aeabff58 100644 --- a/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.h +++ b/searchcore/src/vespa/searchcore/proton/test/mock_index_manager.h @@ -10,6 +10,7 @@ namespace proton::test { */ struct MockIndexManager : public searchcorespi::IIndexManager { + ~MockIndexManager() override; void putDocument(uint32_t, const Document &, SerialNum, OnWriteDoneType) override {} void removeDocuments(LidVector, SerialNum) override {} void commit(SerialNum, OnWriteDoneType) override {} diff --git a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp index afe5b573f21..d5297fe8f8c 100644 --- a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp +++ b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.cpp @@ -77,11 +77,14 @@ public: : _reconfigurer(reconfigurer), _configure(std::move(configure)) { } + ~ReconfigRunnableTask() override; void run() override { _reconfigurer.reconfigure(std::move(_configure)); } }; +ReconfigRunnableTask::~ReconfigRunnableTask() = default; + SerialNum noSerialNumHigh = std::numeric_limits<SerialNum>::max(); @@ -164,6 +167,8 @@ DiskIndexWithDestructorCallback::getSearchableStats() const } // namespace +IndexMaintainer::FrozenMemoryIndexRef::~FrozenMemoryIndexRef() = default; + IndexMaintainer::FusionArgs::FusionArgs() : _new_fusion_id(0u), _changeGens(), diff --git a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h index fa7a9145a3c..b4bba209937 100644 --- a/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h +++ b/searchcorespi/src/vespa/searchcorespi/index/indexmaintainer.h @@ -57,6 +57,7 @@ class IndexMaintainer : public IIndexManager, _saveInfo(saveInfo.release()), _absoluteId(absoluteId) { } + ~FrozenMemoryIndexRef(); }; class ChangeGens { diff --git a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp index fa567be9b76..167eaccc2f7 100644 --- a/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp +++ b/searchlib/src/tests/attribute/imported_attribute_vector/imported_attribute_vector_test.cpp @@ -244,6 +244,7 @@ struct SingleStringAttrFixture : Fixture { SingleStringAttrFixture() : Fixture() { setup(); } + ~SingleStringAttrFixture() override; void setup() { this->template reset_with_single_value_reference_mappings<StringAttribute, const char*>( @@ -253,6 +254,8 @@ struct SingleStringAttrFixture : Fixture { } }; +SingleStringAttrFixture::~SingleStringAttrFixture() = default; + TEST_F("Single-valued string attribute values can be retrieved via reference", SingleStringAttrFixture) { char buf[64]; @@ -329,6 +332,7 @@ struct MultiStringAttrFixture : Fixture { MultiStringAttrFixture() : Fixture() { setup(); } + ~MultiStringAttrFixture() override; void setup() { reset_with_array_value_reference_mappings<StringAttribute, const char *>( @@ -338,6 +342,8 @@ struct MultiStringAttrFixture : Fixture { } }; +MultiStringAttrFixture::~MultiStringAttrFixture() = default; + TEST_F("Multi-valued string attribute values can be retrieved via reference", MultiStringAttrFixture) { assert_multi_value_matches<const char*>(f, DocId(2), f.doc3_values, string_eq); assert_multi_value_matches<const char*>(f, DocId(4), f.doc7_values, string_eq); @@ -368,6 +374,7 @@ struct WeightedMultiStringAttrFixture : Fixture { WeightedMultiStringAttrFixture() : Fixture() { setup(); } + ~WeightedMultiStringAttrFixture() override; void setup() { reset_with_wset_value_reference_mappings<StringAttribute, WeightedString>( @@ -377,6 +384,8 @@ struct WeightedMultiStringAttrFixture : Fixture { } }; +WeightedMultiStringAttrFixture::~WeightedMultiStringAttrFixture() = default; + TEST_F("Weighted string attribute values can be retrieved via reference", WeightedMultiStringAttrFixture) { assert_multi_value_matches<WeightedString>(f, DocId(1), f.doc3_values); assert_multi_value_matches<WeightedString>(f, DocId(3), f.doc7_values); @@ -523,6 +532,7 @@ struct TensorAttrFixture : Fixture { { setup(dense); } + ~TensorAttrFixture() override; void setup(bool dense) { if (dense) { tensor1 = createTensor(TensorSpec("tensor(x[2])").add({{"x", 1}}, 11)); @@ -562,6 +572,7 @@ struct TensorAttrFixture : Fixture { } }; +TensorAttrFixture::~TensorAttrFixture() = default; TEST_F("Imported sparse tensor", TensorAttrFixture(false)) { diff --git a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp index 35011c052d2..6cb0dec3c1f 100644 --- a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp +++ b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp @@ -21,6 +21,7 @@ struct Fixture : ImportedAttributeFixture { Fixture(bool useSearchCache = false, FastSearchConfig fastSearch = FastSearchConfig::Default) : ImportedAttributeFixture(useSearchCache, fastSearch) {} + ~Fixture() override; std::unique_ptr<ImportedSearchContext> create_context(std::unique_ptr<QueryTermSimple> term) { @@ -50,6 +51,8 @@ struct Fixture : ImportedAttributeFixture { } }; +Fixture::~Fixture() = default; + template <typename Iterator> bool is_hit_with_weight(Iterator& iter, TermFieldMatchData& match, DocId lid, int32_t weight) { if (!EXPECT_TRUE(iter.seek(lid))) { @@ -155,8 +158,11 @@ struct ArrayValueFixture : Fixture { {DocId(4), dummy_gid(7), DocId(7), doc7_values}, {DocId(5), dummy_gid(8), DocId(8), doc8_values}}); } + ~ArrayValueFixture() override; }; +ArrayValueFixture::~ArrayValueFixture() = default; + TEST_F("Non-strict iterator handles unmapped LIDs", ArrayValueFixture) { auto ctx = f.create_context(word_term("1234")); TermFieldMatchData match; @@ -196,8 +202,11 @@ struct WsetValueFixture : Fixture { {DocId(4), dummy_gid(4), DocId(4), doc4_values}, {DocId(6), dummy_gid(7), DocId(7), doc7_values}}); } + ~WsetValueFixture() override; }; +WsetValueFixture::~WsetValueFixture() = default; + TEST_F("Non-strict iterator unpacks target match data for weighted set hit", WsetValueFixture) { auto ctx = f.create_context(word_term("foo")); TermFieldMatchData match; @@ -243,8 +252,11 @@ struct SingleValueFixture : Fixture { {DocId(5), dummy_gid(8), DocId(8), 5678}, {DocId(7), dummy_gid(9), DocId(9), 4321}}); } + ~SingleValueFixture() override; }; +SingleValueFixture::~SingleValueFixture() = default; + // Strict iteration implicitly tests unmapped LIDs by its nature, so we don't have a separate test for that. TEST_F("Strict iterator seeks to first available hit LID", SingleValueFixture) { @@ -390,8 +402,11 @@ struct SearchCacheFixture : Fixture { FastSearchConfig::ExplicitlyEnabled, FilterConfig::ExplicitlyEnabled); } + ~SearchCacheFixture() override; }; +SearchCacheFixture::~SearchCacheFixture() = default; + BitVectorSearchCache::Entry::SP makeSearchCacheEntry(const std::vector<uint32_t> docIds, uint32_t docIdLimit) { diff --git a/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp b/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp index 29f7b5c0276..4f037415b35 100644 --- a/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp +++ b/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp @@ -1055,7 +1055,7 @@ SearchContextTest::testSearchIteratorUnpacking() { Config cfg(BasicType::INT32, CollectionType::SINGLE); cfg.setFastSearch(true); - config.emplace_back("sfs-int32", cfg); + config.emplace_back(vespalib::string("sfs-int32"), cfg); } { Config cfg(BasicType::INT32, CollectionType::ARRAY); diff --git a/searchlib/src/tests/bitcompression/expgolomb/expgolomb_test.cpp b/searchlib/src/tests/bitcompression/expgolomb/expgolomb_test.cpp index a1a74a1d68c..1ee4e9614e0 100644 --- a/searchlib/src/tests/bitcompression/expgolomb/expgolomb_test.cpp +++ b/searchlib/src/tests/bitcompression/expgolomb/expgolomb_test.cpp @@ -205,7 +205,12 @@ public: void addConstKFactory(int kValue, IDecodeFuncFactory factory) { (void) kValue; assert(static_cast<unsigned int>(kValue) == _constK.size()); +#pragma GCC diagnostic push +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 12 +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif _constK.push_back(factory); +#pragma GCC diagnostic pop } IDecodeFuncFactory getConstKFactory(int kValue) const { diff --git a/searchlib/src/tests/docstore/document_store/document_store_test.cpp b/searchlib/src/tests/docstore/document_store/document_store_test.cpp index f2bec30a349..0483ea26423 100644 --- a/searchlib/src/tests/docstore/document_store/document_store_test.cpp +++ b/searchlib/src/tests/docstore/document_store/document_store_test.cpp @@ -13,6 +13,7 @@ document::DocumentTypeRepo repo; struct NullDataStore : IDataStore { NullDataStore() : IDataStore("") {} + ~NullDataStore() override; ssize_t read(uint32_t, vespalib::DataBuffer &) const override { return 0; } void read(const LidVector &, IBufferVisitor &) const override { } void write(uint64_t, uint32_t, const void *, size_t) override {} @@ -46,6 +47,8 @@ struct NullDataStore : IDataStore { void shrinkLidSpace() override {} }; +NullDataStore::~NullDataStore() = default; + TEST_FFF("require that uncache docstore lookups are counted", DocumentStore::Config(CompressionConfig::NONE, 0, 0), NullDataStore(), DocumentStore(f1, f2)) diff --git a/searchlib/src/tests/features/element_similarity_feature/element_similarity_feature_test.cpp b/searchlib/src/tests/features/element_similarity_feature/element_similarity_feature_test.cpp index dd1dc5b3689..97508e1f582 100644 --- a/searchlib/src/tests/features/element_similarity_feature/element_similarity_feature_test.cpp +++ b/searchlib/src/tests/features/element_similarity_feature/element_similarity_feature_test.cpp @@ -65,11 +65,14 @@ struct IndexFixture { struct FeatureDumpFixture : public IDumpFeatureVisitor { std::vector<vespalib::string> actual; FeatureDumpFixture() : IDumpFeatureVisitor(), actual() {} + ~FeatureDumpFixture() override; virtual void visitDumpFeature(const vespalib::string &name) override { actual.push_back(name); } }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + struct RankFixture : BlueprintFactoryFixture { RankFixture() : BlueprintFactoryFixture() {} double get_feature(const vespalib::string &query, const FtIndex &index, const vespalib::string &select, diff --git a/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp b/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp index 72613cd0fd4..a32d52d06a0 100644 --- a/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp +++ b/searchlib/src/tests/features/imported_dot_product/imported_dot_product_test.cpp @@ -94,6 +94,7 @@ struct FixtureBase : ImportedAttributeFixture { struct ArrayFixture : FixtureBase { + ~ArrayFixture() override; void setup_integer_mappings(BasicType int_type) override { reset_with_array_value_reference_mappings<IntegerAttribute, int64_t>( int_type, @@ -168,6 +169,8 @@ struct ArrayFixture : FixtureBase { } }; +ArrayFixture::~ArrayFixture() = default; + TEST_F("Dense i32/i64 array dot products can be evaluated with string parameter", ArrayFixture) { f.check_all_integer_executions(2*2 + 3*3 + 5*4, "[2 3 4]", DocId(1)); } @@ -261,8 +264,11 @@ struct WsetFixture : FixtureBase { int_type, {{DocId(3), dummy_gid(7), DocId(7), doc7_values}}); } + ~WsetFixture() override; }; +WsetFixture::~WsetFixture() = default; + TEST_F("i32/i64 wset dot products can be evaluated with string parameter", WsetFixture) { f.check_all_integer_executions(21*7 + 19*13, "{200:21,300:19,999:1234}", DocId(3)); } diff --git a/searchlib/src/tests/features/item_raw_score/item_raw_score_test.cpp b/searchlib/src/tests/features/item_raw_score/item_raw_score_test.cpp index 67924d2019a..ab6fa1c0596 100644 --- a/searchlib/src/tests/features/item_raw_score/item_raw_score_test.cpp +++ b/searchlib/src/tests/features/item_raw_score/item_raw_score_test.cpp @@ -43,8 +43,11 @@ struct FeatureDumpFixture : public IDumpFeatureVisitor { TEST_ERROR("no features should be dumped"); } FeatureDumpFixture() : IDumpFeatureVisitor() {} + ~FeatureDumpFixture() override; }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + struct RankFixture : BlueprintFactoryFixture, IndexFixture { QueryEnvironment queryEnv; RankSetup rankSetup; diff --git a/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp b/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp index 4d9318311f3..e4743a4a783 100644 --- a/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp +++ b/searchlib/src/tests/features/native_dot_product/native_dot_product_test.cpp @@ -42,8 +42,11 @@ struct FeatureDumpFixture : public IDumpFeatureVisitor { TEST_ERROR("no features should be dumped"); } FeatureDumpFixture() : IDumpFeatureVisitor() {} + ~FeatureDumpFixture() override; }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + std::vector<uint32_t> vec() { std::vector<uint32_t> ret; return ret; diff --git a/searchlib/src/tests/features/nns_closeness/nns_closeness_test.cpp b/searchlib/src/tests/features/nns_closeness/nns_closeness_test.cpp index 713abeada6a..c7667b2cecd 100644 --- a/searchlib/src/tests/features/nns_closeness/nns_closeness_test.cpp +++ b/searchlib/src/tests/features/nns_closeness/nns_closeness_test.cpp @@ -45,8 +45,11 @@ struct FeatureDumpFixture : public IDumpFeatureVisitor { TEST_ERROR("no features should be dumped"); } FeatureDumpFixture() : IDumpFeatureVisitor() {} + ~FeatureDumpFixture() override; }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + struct RankFixture : BlueprintFactoryFixture, IndexFixture { QueryEnvironment queryEnv; RankSetup rankSetup; diff --git a/searchlib/src/tests/features/nns_distance/nns_distance_test.cpp b/searchlib/src/tests/features/nns_distance/nns_distance_test.cpp index c3973a6493c..1e81b5576c1 100644 --- a/searchlib/src/tests/features/nns_distance/nns_distance_test.cpp +++ b/searchlib/src/tests/features/nns_distance/nns_distance_test.cpp @@ -45,8 +45,11 @@ struct FeatureDumpFixture : public IDumpFeatureVisitor { TEST_ERROR("no features should be dumped"); } FeatureDumpFixture() : IDumpFeatureVisitor() {} + ~FeatureDumpFixture() override; }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + struct RankFixture : BlueprintFactoryFixture, IndexFixture { QueryEnvironment queryEnv; RankSetup rankSetup; diff --git a/searchlib/src/tests/features/raw_score/raw_score_test.cpp b/searchlib/src/tests/features/raw_score/raw_score_test.cpp index b3ad2f3c803..1fb3f4050a1 100644 --- a/searchlib/src/tests/features/raw_score/raw_score_test.cpp +++ b/searchlib/src/tests/features/raw_score/raw_score_test.cpp @@ -40,8 +40,11 @@ struct FeatureDumpFixture : public IDumpFeatureVisitor { TEST_ERROR("no features should be dumped"); } FeatureDumpFixture() : IDumpFeatureVisitor() {} + ~FeatureDumpFixture() override; }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + struct RankFixture : BlueprintFactoryFixture, IndexFixture { QueryEnvironment queryEnv; RankSetup rankSetup; diff --git a/searchlib/src/tests/features/subqueries/subqueries_test.cpp b/searchlib/src/tests/features/subqueries/subqueries_test.cpp index be7f6bb5e9a..cc6febead3c 100644 --- a/searchlib/src/tests/features/subqueries/subqueries_test.cpp +++ b/searchlib/src/tests/features/subqueries/subqueries_test.cpp @@ -38,8 +38,11 @@ struct FeatureDumpFixture : public IDumpFeatureVisitor { TEST_ERROR("no features should be dumped"); } FeatureDumpFixture() : IDumpFeatureVisitor() {} + ~FeatureDumpFixture() override; }; +FeatureDumpFixture::~FeatureDumpFixture() = default; + struct RankFixture : BlueprintFactoryFixture, IndexFixture { QueryEnvironment queryEnv; RankSetup rankSetup; diff --git a/searchlib/src/tests/grouping/sketch_test.cpp b/searchlib/src/tests/grouping/sketch_test.cpp index 2b5756b1950..10f5cbaa8ef 100644 --- a/searchlib/src/tests/grouping/sketch_test.cpp +++ b/searchlib/src/tests/grouping/sketch_test.cpp @@ -27,7 +27,7 @@ TEST("require that normal sketch is initialized") { template <typename NormalSketch> void checkBucketValue(NormalSketch &sketch, size_t bucket, uint32_t value) { #pragma GCC diagnostic push -#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 11 +#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 11 || __GNUC__ <= 12) #pragma GCC diagnostic ignored "-Warray-bounds" #endif EXPECT_EQUAL(value, static_cast<size_t>(sketch.bucket[bucket])); diff --git a/searchlib/src/tests/hitcollector/hitcollector_test.cpp b/searchlib/src/tests/hitcollector/hitcollector_test.cpp index ed68c47ea23..3a7bce17288 100644 --- a/searchlib/src/tests/hitcollector/hitcollector_test.cpp +++ b/searchlib/src/tests/hitcollector/hitcollector_test.cpp @@ -179,18 +179,24 @@ struct Fixture { struct AscendingScoreFixture : Fixture { AscendingScoreFixture() : Fixture() {} + ~AscendingScoreFixture() override; HitRank calculateScore(uint32_t i) override { return i + 100; } }; +AscendingScoreFixture::~AscendingScoreFixture() = default; + struct DescendingScoreFixture : Fixture { DescendingScoreFixture() : Fixture() {} + ~DescendingScoreFixture() override; HitRank calculateScore(uint32_t i) override { return 100 - i; } }; +DescendingScoreFixture::~DescendingScoreFixture() = default; + TEST_F("testReRank - empty", Fixture) { EXPECT_EQUAL(0u, f.reRank()); } diff --git a/searchlib/src/tests/queryeval/weak_and/rise_wand.h b/searchlib/src/tests/queryeval/weak_and/rise_wand.h index 87f59eb3d78..7a5e46c05ea 100644 --- a/searchlib/src/tests/queryeval/weak_and/rise_wand.h +++ b/searchlib/src/tests/queryeval/weak_and/rise_wand.h @@ -36,7 +36,7 @@ public: private: // comparator class that compares two streams. The variables a and b are // logically indices into the streams vector. - class StreamComparator : public std::binary_function<uint16_t, uint16_t, bool> + class StreamComparator { private: const docid_t *_streamDocIds; diff --git a/searchlib/src/tests/queryeval/weak_and/wand_bench_setup.hpp b/searchlib/src/tests/queryeval/weak_and/wand_bench_setup.hpp index 14de5ec6475..87eec226221 100644 --- a/searchlib/src/tests/queryeval/weak_and/wand_bench_setup.hpp +++ b/searchlib/src/tests/queryeval/weak_and/wand_bench_setup.hpp @@ -97,34 +97,44 @@ struct WandFactory { struct VespaWandFactory : WandFactory { uint32_t n; VespaWandFactory(uint32_t n_in) : n(n_in) {} + ~VespaWandFactory() override; virtual std::string name() const override { return make_string("VESPA WAND (n=%u)", n); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(WeakAndSearch::create(terms, n, true)); } }; +VespaWandFactory::~VespaWandFactory() = default; + struct VespaArrayWandFactory : WandFactory { uint32_t n; VespaArrayWandFactory(uint32_t n_in) : n(n_in) {} + ~VespaArrayWandFactory() override; virtual std::string name() const override { return make_string("VESPA ARRAY WAND (n=%u)", n); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(WeakAndSearch::createArrayWand(terms, n, true)); } }; +VespaArrayWandFactory::~VespaArrayWandFactory() = default; + struct VespaHeapWandFactory : WandFactory { uint32_t n; VespaHeapWandFactory(uint32_t n_in) : n(n_in) {} + ~VespaHeapWandFactory() override; virtual std::string name() const override { return make_string("VESPA HEAP WAND (n=%u)", n); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(WeakAndSearch::createHeapWand(terms, n, true)); } }; +VespaHeapWandFactory::~VespaHeapWandFactory() = default; + struct VespaParallelWandFactory : public WandFactory { SharedWeakAndPriorityQueue scores; TermFieldMatchData rootMatchData; VespaParallelWandFactory(uint32_t n) : scores(n), rootMatchData() {} + ~VespaParallelWandFactory() override; virtual std::string name() const override { return make_string("VESPA PWAND (n=%u)", scores.getScoresToTrack()); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(ParallelWeakAndSearch::create(terms, @@ -133,8 +143,11 @@ struct VespaParallelWandFactory : public WandFactory { } }; +VespaParallelWandFactory::~VespaParallelWandFactory() = default; + struct VespaParallelArrayWandFactory : public VespaParallelWandFactory { VespaParallelArrayWandFactory(uint32_t n) : VespaParallelWandFactory(n) {} + ~VespaParallelArrayWandFactory() override; virtual std::string name() const override { return make_string("VESPA ARRAY PWAND (n=%u)", scores.getScoresToTrack()); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(ParallelWeakAndSearch::createArrayWand(terms, @@ -143,8 +156,11 @@ struct VespaParallelArrayWandFactory : public VespaParallelWandFactory { } }; +VespaParallelArrayWandFactory::~VespaParallelArrayWandFactory() = default; + struct VespaParallelHeapWandFactory : public VespaParallelWandFactory { VespaParallelHeapWandFactory(uint32_t n) : VespaParallelWandFactory(n) {} + ~VespaParallelHeapWandFactory() override; virtual std::string name() const override { return make_string("VESPA HEAP PWAND (n=%u)", scores.getScoresToTrack()); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(ParallelWeakAndSearch::createHeapWand(terms, @@ -153,29 +169,38 @@ struct VespaParallelHeapWandFactory : public VespaParallelWandFactory { } }; +VespaParallelHeapWandFactory::~VespaParallelHeapWandFactory() = default; + struct TermFrequencyRiseWandFactory : WandFactory { uint32_t n; TermFrequencyRiseWandFactory(uint32_t n_in) : n(n_in) {} + ~TermFrequencyRiseWandFactory() override; virtual std::string name() const override { return make_string("RISE WAND TF (n=%u)", n); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(new rise::TermFrequencyRiseWand(terms, n)); } }; +TermFrequencyRiseWandFactory::~TermFrequencyRiseWandFactory() = default; + struct DotProductRiseWandFactory : WandFactory { uint32_t n; DotProductRiseWandFactory(uint32_t n_in) : n(n_in) {} + ~DotProductRiseWandFactory() override; virtual std::string name() const override { return make_string("RISE WAND DP (n=%u)", n); } virtual SearchIterator::UP create(const wand::Terms &terms) override { return SearchIterator::UP(new rise::DotProductRiseWand(terms, n)); } }; +DotProductRiseWandFactory::~DotProductRiseWandFactory() = default; + struct FilterFactory : WandFactory { WandFactory &factory; Stats stats; uint32_t n; FilterFactory(WandFactory &f, uint32_t n_in) : factory(f), n(n_in) {} + ~FilterFactory() override; virtual std::string name() const override { return make_string("Filter (mod=%u) [%s]", n, factory.name().c_str()); } virtual SearchIterator::UP create(const wand::Terms &terms) override { AndNotSearch::Children children; @@ -185,6 +210,8 @@ struct FilterFactory : WandFactory { } }; +FilterFactory::~FilterFactory() = default; + struct Setup { Stats stats; vespalib::duration minTime; @@ -223,6 +250,7 @@ struct WandSetup : Setup { uint32_t weight; MatchData::UP matchData; WandSetup(WandFactory &f, uint32_t c, uint32_t l) : Setup(), factory(f), childCnt(c), limit(l), weight(100), matchData() {} + ~WandSetup() override; virtual std::string name() const override { return make_string("Wand Setup (terms=%u,docs=%u) [%s]", childCnt, limit, factory.name().c_str()); } @@ -242,4 +270,6 @@ struct WandSetup : Setup { } }; +WandSetup::~WandSetup() = default; + } // namespace <unnamed> diff --git a/searchlib/src/tests/sort/sort_test.cpp b/searchlib/src/tests/sort/sort_test.cpp index 54a3542e82b..9c48498eae9 100644 --- a/searchlib/src/tests/sort/sort_test.cpp +++ b/searchlib/src/tests/sort/sort_test.cpp @@ -48,7 +48,7 @@ struct LoadedStrings } }; - class ValueCompare : public std::binary_function<LoadedStrings, LoadedStrings, bool> { + class ValueCompare { public: bool operator() (const LoadedStrings & x, const LoadedStrings & y) const { return strcmp(x._value, y._value) < 0; diff --git a/searchlib/src/vespa/searchlib/aggregation/group.h b/searchlib/src/vespa/searchlib/aggregation/group.h index 4b06bcd8cae..202c5085133 100644 --- a/searchlib/src/vespa/searchlib/aggregation/group.h +++ b/searchlib/src/vespa/searchlib/aggregation/group.h @@ -39,7 +39,7 @@ public: using UP = std::unique_ptr<Group>; typedef Group * ChildP; typedef ChildP * GroupList; - struct GroupEqual : public std::binary_function<ChildP, ChildP, bool> { + struct GroupEqual { GroupEqual(const GroupList * v) : _v(v) { } bool operator()(uint32_t a, uint32_t b) { return (*_v)[a]->getId().cmpFast((*_v)[b]->getId()) == 0; } bool operator()(const Group & a, uint32_t b) { return a.getId().cmpFast((*_v)[b]->getId()) == 0; } diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index 213bbfc3493..906400f50a5 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -235,6 +235,8 @@ public: set_allow_termwise_eval(true); } + ~LocationPreFilterBlueprint(); + bool should_use() const { return _should_use; } SearchIterator::UP @@ -258,6 +260,8 @@ public: } }; +LocationPreFilterBlueprint::~LocationPreFilterBlueprint() = default; + //----------------------------------------------------------------------------- class LocationPostFilterBlueprint : public ComplexLeafBlueprint @@ -282,6 +286,8 @@ public: setEstimate(estimate); } + ~LocationPostFilterBlueprint(); + const common::Location &location() const { return _location; } SearchIterator::UP @@ -334,6 +340,8 @@ make_location_blueprint(const FieldSpec &field, const IAttributeVector &attribut return root; } +LocationPostFilterBlueprint::~LocationPostFilterBlueprint() = default; + class LookupKey : public IDocumentWeightAttribute::LookupKey { public: LookupKey(MultiTerm & terms, uint32_t index) : _terms(terms), _index(index) {} @@ -381,6 +389,7 @@ public: _weights.reserve(size_hint); _terms.reserve(size_hint); } + ~DirectWeightedSetBlueprint() override; void addTerm(const IDocumentWeightAttribute::LookupKey & key, int32_t weight) { IDocumentWeightAttribute::LookupResult result = _attr.lookup(key, _dictionary_snapshot); @@ -423,6 +432,9 @@ public: }; template <typename SearchType> +DirectWeightedSetBlueprint<SearchType>::~DirectWeightedSetBlueprint() = default; + +template <typename SearchType> std::unique_ptr<SearchIterator> DirectWeightedSetBlueprint<SearchType>::createFilterSearch(bool, FilterConstraint) const { @@ -467,6 +479,8 @@ public: _terms.reserve(size_hint); } + ~DirectWandBlueprint(); + void addTerm(const IDocumentWeightAttribute::LookupKey & key, int32_t weight) { IDocumentWeightAttribute::LookupResult result = _attr.lookup(key, _dictionary_snapshot); HitEstimate childEst(result.posting_size, (result.posting_size == 0)); @@ -497,6 +511,8 @@ public: bool always_needs_unpack() const override { return true; } }; +DirectWandBlueprint::~DirectWandBlueprint() = default; + std::unique_ptr<SearchIterator> DirectWandBlueprint::createFilterSearch(bool, FilterConstraint constraint) const { diff --git a/searchlib/src/vespa/searchlib/attribute/attrvector.cpp b/searchlib/src/vespa/searchlib/attribute/attrvector.cpp index 6b692ee4b27..0179841e7fa 100644 --- a/searchlib/src/vespa/searchlib/attribute/attrvector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attrvector.cpp @@ -99,7 +99,7 @@ void StringDirectAttribute::onSave(IAttributeSaveTarget & saveTarget) } } -class stringComp : public std::binary_function<uint32_t, uint32_t, bool> { +class stringComp { public: stringComp(const char * buffer) : _buffer(buffer) { } bool operator()(uint32_t x, uint32_t y) const { return strcmp(_buffer+x, _buffer+y) < 0; } diff --git a/searchlib/src/vespa/searchlib/attribute/changevector.hpp b/searchlib/src/vespa/searchlib/attribute/changevector.hpp index 43787bf8bd4..a81c14aa85c 100644 --- a/searchlib/src/vespa/searchlib/attribute/changevector.hpp +++ b/searchlib/src/vespa/searchlib/attribute/changevector.hpp @@ -5,6 +5,7 @@ #include "changevector.h" #include <vespa/vespalib/util/memoryusage.h> #include <vespa/vespalib/util/alloc.h> +#include <algorithm> namespace search { diff --git a/searchlib/src/vespa/searchlib/attribute/extendableattributes.h b/searchlib/src/vespa/searchlib/attribute/extendableattributes.h index 33b8544f9fe..bb8197c1908 100644 --- a/searchlib/src/vespa/searchlib/attribute/extendableattributes.h +++ b/searchlib/src/vespa/searchlib/attribute/extendableattributes.h @@ -124,6 +124,7 @@ public: MultiExtAttribute(const vespalib::string &name) : Super(name, Config(BasicType::fromType(static_cast<T>(0)), attribute::CollectionType::ARRAY)) {} + ~MultiExtAttribute() override; bool addDoc(typename Super::DocId &docId) override { docId = this->_idx.size() - 1; @@ -147,6 +148,9 @@ public: } }; +template <typename T> +MultiExtAttribute<T>::~MultiExtAttribute() = default; + typedef MultiExtAttribute<int8_t> MultiInt8ExtAttribute; typedef MultiExtAttribute<int16_t> MultiInt16ExtAttribute; typedef MultiExtAttribute<int32_t> MultiInt32ExtAttribute; diff --git a/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h b/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h index fdf9ab624ad..96bdc147559 100644 --- a/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h +++ b/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h @@ -33,9 +33,7 @@ public: } }; - class EnumCompare : public std::binary_function<LoadedEnumAttribute, - LoadedEnumAttribute, - bool> + class EnumCompare { public: bool diff --git a/searchlib/src/vespa/searchlib/attribute/loadednumericvalue.h b/searchlib/src/vespa/searchlib/attribute/loadednumericvalue.h index bfc636d79b9..934d20d57b2 100644 --- a/searchlib/src/vespa/searchlib/attribute/loadednumericvalue.h +++ b/searchlib/src/vespa/searchlib/attribute/loadednumericvalue.h @@ -20,7 +20,7 @@ struct LoadedNumericValue : public LoadedValue<T> { LoadedNumericValue() : LoadedValue<T>() { } - class ValueCompare : public std::binary_function<LoadedNumericValue<T>, LoadedNumericValue<T>, bool> + class ValueCompare { public: bool operator()(const LoadedNumericValue<T> &x, const LoadedNumericValue<T> &y) const { diff --git a/searchlib/src/vespa/searchlib/attribute/loadedvalue.h b/searchlib/src/vespa/searchlib/attribute/loadedvalue.h index b8f938838d2..ab20c9fbe69 100644 --- a/searchlib/src/vespa/searchlib/attribute/loadedvalue.h +++ b/searchlib/src/vespa/searchlib/attribute/loadedvalue.h @@ -40,9 +40,7 @@ public: } }; - class DocOrderCompare : public std::binary_function<LoadedValue<T>, - LoadedValue<T>, - bool> + class DocOrderCompare { public: bool diff --git a/searchlib/src/vespa/searchlib/attribute/sourceselector.cpp b/searchlib/src/vespa/searchlib/attribute/sourceselector.cpp index 3bc85783c2f..0a39e5defc9 100644 --- a/searchlib/src/vespa/searchlib/attribute/sourceselector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/sourceselector.cpp @@ -64,6 +64,7 @@ SourceSelector::SaveInfo::SaveInfo(const vespalib::string & baseFileName, sourceStore.save(_memSaver, _header._baseFileName); } +SourceSelector::SaveInfo::~SaveInfo() = default; bool SourceSelector::SaveInfo::save(const TuneFileAttributes &tuneFileAttributes, const FileHeaderContext &fileHeaderContext) diff --git a/searchlib/src/vespa/searchlib/attribute/sourceselector.h b/searchlib/src/vespa/searchlib/attribute/sourceselector.h index 7ab79ea34e8..de92abf212e 100644 --- a/searchlib/src/vespa/searchlib/attribute/sourceselector.h +++ b/searchlib/src/vespa/searchlib/attribute/sourceselector.h @@ -42,6 +42,7 @@ public: uint32_t baseId, uint32_t docIdLimit, AttributeVector & sourceStore); + ~SaveInfo(); const HeaderInfo & getHeader() const { return _header; } bool save(const TuneFileAttributes &tuneFileAttributes, const search::common::FileHeaderContext &fileHeaderContext); diff --git a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp index ec9b212fcf8..57882ddf1ae 100644 --- a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp +++ b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp @@ -107,7 +107,7 @@ public: } }; -class StdSortDataCharCompare : public std::binary_function<SortDataChar, SortDataChar, bool> +class StdSortDataCharCompare { public: bool operator() (const SortDataChar & x, const SortDataChar & y) const { diff --git a/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp b/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp index f33b571f263..60d04d7e3ad 100644 --- a/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp +++ b/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp @@ -5,6 +5,7 @@ #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/guard.h> #include <cassert> +#include <algorithm> #include <vespa/log/log.h> LOG_SETUP(".indexmetainfo"); diff --git a/searchlib/src/vespa/searchlib/common/sortresults.cpp b/searchlib/src/vespa/searchlib/common/sortresults.cpp index 7510ae162ce..8a9af3af828 100644 --- a/searchlib/src/vespa/searchlib/common/sortresults.cpp +++ b/searchlib/src/vespa/searchlib/common/sortresults.cpp @@ -425,7 +425,7 @@ FastS_insertion_sort(T a[], uint32_t n, Compare *compobj) } } -class StdSortDataCompare : public std::binary_function<FastS_SortSpec::SortData, FastS_SortSpec::SortData, bool> +class StdSortDataCompare { public: StdSortDataCompare(const uint8_t * s) : _sortSpec(s) { } diff --git a/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.cpp b/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.cpp index 180151264a8..89ea14a94ac 100644 --- a/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.cpp +++ b/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.cpp @@ -40,8 +40,14 @@ RawBucketResultNode::RawBucketResultNode() _to(new RawResultNode()) {} +RawBucketResultNode::RawBucketResultNode(const RawBucketResultNode&) = default; + RawBucketResultNode::~RawBucketResultNode() = default; +RawBucketResultNode& RawBucketResultNode::operator=(const RawBucketResultNode&) = default; + +RawBucketResultNode& RawBucketResultNode::operator=(RawBucketResultNode&&) noexcept = default; + int RawBucketResultNode::onCmp(const Identifiable & rhs) const { diff --git a/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.h b/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.h index eaca52de4f6..436304a3dce 100644 --- a/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.h +++ b/searchlib/src/vespa/searchlib/expression/rawbucketresultnode.h @@ -23,8 +23,12 @@ public: DECLARE_EXPRESSIONNODE(RawBucketResultNode); DECLARE_NBO_SERIALIZE; RawBucketResultNode(); + RawBucketResultNode(const RawBucketResultNode&); + RawBucketResultNode(RawBucketResultNode&&) noexcept = default; RawBucketResultNode(ResultNode::UP from, ResultNode::UP to) : _from(from.release()), _to(to.release()) {} ~RawBucketResultNode(); + RawBucketResultNode& operator=(const RawBucketResultNode&); + RawBucketResultNode& operator=(RawBucketResultNode&&) noexcept; size_t hash() const override; int onCmp(const Identifiable & b) const override; int contains(const RawBucketResultNode & b) const; diff --git a/searchlib/src/vespa/searchlib/expression/resultvector.h b/searchlib/src/vespa/searchlib/expression/resultvector.h index 171659993ac..81d73e9b1f5 100644 --- a/searchlib/src/vespa/searchlib/expression/resultvector.h +++ b/searchlib/src/vespa/searchlib/expression/resultvector.h @@ -57,20 +57,20 @@ private: template <typename B> struct cmpT { - struct less : public std::binary_function<B, B, bool> { + struct less { bool operator()(const B & a, const B & b) { return a.cmp(b) < 0; } }; - struct equal : public std::binary_function<B, B, bool> { + struct equal { bool operator()(const B & a, const B & b) { return a.cmp(b) == 0; } }; }; template <typename B, typename V> struct contains { - struct less : public std::binary_function<B, V, bool> { + struct less { bool operator()(const B & a, const V & b) { return a.contains(b) < 0; } }; - struct equal : public std::binary_function<B, V, bool> { + struct equal { bool operator()(const B & a, const V & b) { return a.contains(b) == 0; } }; }; diff --git a/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.cpp b/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.cpp index 6958bba2fba..5aadddfa0e2 100644 --- a/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.cpp +++ b/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.cpp @@ -9,6 +9,12 @@ IMPLEMENT_RESULTNODE(StringBucketResultNode, BucketResultNode); StringBucketResultNode StringBucketResultNode::_nullResult; +StringBucketResultNode::StringBucketResultNode(const StringBucketResultNode&) = default; + +StringBucketResultNode& StringBucketResultNode::operator=(const StringBucketResultNode&) = default; + +StringBucketResultNode& StringBucketResultNode::operator=(StringBucketResultNode&&) = default; + size_t StringBucketResultNode::hash() const { diff --git a/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.h b/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.h index 59120680732..bf270d64729 100644 --- a/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.h +++ b/searchlib/src/vespa/searchlib/expression/stringbucketresultnode.h @@ -23,9 +23,13 @@ public: DECLARE_EXPRESSIONNODE(StringBucketResultNode); DECLARE_NBO_SERIALIZE; StringBucketResultNode(); + StringBucketResultNode(const StringBucketResultNode&); + StringBucketResultNode(StringBucketResultNode&&) noexcept = default; StringBucketResultNode(vespalib::stringref from, vespalib::stringref to); StringBucketResultNode(ResultNode::UP from, ResultNode::UP to) : _from(from.release()), _to(to.release()) {} ~StringBucketResultNode(); + StringBucketResultNode& operator=(const StringBucketResultNode&); + StringBucketResultNode& operator=(StringBucketResultNode&&); size_t hash() const override; int onCmp(const Identifiable & b) const override; int contains(const StringBucketResultNode & b) const; diff --git a/searchlib/src/vespa/searchlib/features/closenessfeature.cpp b/searchlib/src/vespa/searchlib/features/closenessfeature.cpp index e98573d7a6b..04fc2a263be 100644 --- a/searchlib/src/vespa/searchlib/features/closenessfeature.cpp +++ b/searchlib/src/vespa/searchlib/features/closenessfeature.cpp @@ -107,6 +107,8 @@ ClosenessBlueprint::ClosenessBlueprint() : { } +ClosenessBlueprint::~ClosenessBlueprint() = default; + void ClosenessBlueprint::visitDumpFeatures(const IIndexEnvironment &, IDumpFeatureVisitor &) const diff --git a/searchlib/src/vespa/searchlib/features/closenessfeature.h b/searchlib/src/vespa/searchlib/features/closenessfeature.h index e45cf9687e0..799495eaff5 100644 --- a/searchlib/src/vespa/searchlib/features/closenessfeature.h +++ b/searchlib/src/vespa/searchlib/features/closenessfeature.h @@ -38,6 +38,7 @@ private: public: ClosenessBlueprint(); + ~ClosenessBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment & env, fef::IDumpFeatureVisitor & visitor) const override; fef::Blueprint::UP createInstance() const override; fef::ParameterDescriptions getDescriptions() const override { diff --git a/searchlib/src/vespa/searchlib/features/element_completeness_feature.cpp b/searchlib/src/vespa/searchlib/features/element_completeness_feature.cpp index 3b481ac69f1..3edfecd9a2c 100644 --- a/searchlib/src/vespa/searchlib/features/element_completeness_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/element_completeness_feature.cpp @@ -96,6 +96,8 @@ ElementCompletenessBlueprint::ElementCompletenessBlueprint() _output.push_back("elementWeight"); } +ElementCompletenessBlueprint::~ElementCompletenessBlueprint() = default; + void ElementCompletenessBlueprint::visitDumpFeatures(const fef::IIndexEnvironment &env, fef::IDumpFeatureVisitor &visitor) const diff --git a/searchlib/src/vespa/searchlib/features/element_completeness_feature.h b/searchlib/src/vespa/searchlib/features/element_completeness_feature.h index 00e0d115f3d..2b1901184f4 100644 --- a/searchlib/src/vespa/searchlib/features/element_completeness_feature.h +++ b/searchlib/src/vespa/searchlib/features/element_completeness_feature.h @@ -100,7 +100,7 @@ private: public: ElementCompletenessBlueprint(); - + ~ElementCompletenessBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment & env, fef::IDumpFeatureVisitor & visitor) const override; fef::Blueprint::UP createInstance() const override; diff --git a/searchlib/src/vespa/searchlib/features/item_raw_score_feature.cpp b/searchlib/src/vespa/searchlib/features/item_raw_score_feature.cpp index b02d336168b..586e086cf97 100644 --- a/searchlib/src/vespa/searchlib/features/item_raw_score_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/item_raw_score_feature.cpp @@ -49,6 +49,8 @@ SimpleItemRawScoreExecutor::handle_bind_match_data(const MatchData &md) //----------------------------------------------------------------------------- +ItemRawScoreBlueprint::~ItemRawScoreBlueprint() = default; + bool ItemRawScoreBlueprint::setup(const IIndexEnvironment &, const ParameterList ¶ms) diff --git a/searchlib/src/vespa/searchlib/features/item_raw_score_feature.h b/searchlib/src/vespa/searchlib/features/item_raw_score_feature.h index 312034b732f..3f93ca5ad75 100644 --- a/searchlib/src/vespa/searchlib/features/item_raw_score_feature.h +++ b/searchlib/src/vespa/searchlib/features/item_raw_score_feature.h @@ -46,6 +46,7 @@ private: vespalib::string _label; public: ItemRawScoreBlueprint() : Blueprint("itemRawScore"), _label() {} + ~ItemRawScoreBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment &, fef::IDumpFeatureVisitor &) const override {} fef::Blueprint::UP createInstance() const override { return Blueprint::UP(new ItemRawScoreBlueprint()); diff --git a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp index 8b47c4e9e81..9472814f581 100644 --- a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.cpp @@ -59,6 +59,8 @@ NativeDotProductExecutor::handle_bind_match_data(const fef::MatchData &md) //----------------------------------------------------------------------------- +NativeDotProductBlueprint::~NativeDotProductBlueprint() = default; + bool NativeDotProductBlueprint::setup(const IIndexEnvironment &, const ParameterList ¶ms) diff --git a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h index adff5663b92..c546ed86501 100644 --- a/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h +++ b/searchlib/src/vespa/searchlib/features/native_dot_product_feature.h @@ -31,6 +31,7 @@ private: const fef::FieldInfo *_field; public: NativeDotProductBlueprint() : Blueprint("nativeDotProduct"), _field(nullptr) {} + ~NativeDotProductBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment &, fef::IDumpFeatureVisitor &) const override {} fef::Blueprint::UP createInstance() const override { return Blueprint::UP(new NativeDotProductBlueprint()); diff --git a/searchlib/src/vespa/searchlib/features/raw_score_feature.cpp b/searchlib/src/vespa/searchlib/features/raw_score_feature.cpp index bedb62e79e4..4e4426a5dab 100644 --- a/searchlib/src/vespa/searchlib/features/raw_score_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/raw_score_feature.cpp @@ -43,6 +43,8 @@ RawScoreExecutor::handle_bind_match_data(const fef::MatchData &md) //----------------------------------------------------------------------------- +RawScoreBlueprint::~RawScoreBlueprint() = default; + bool RawScoreBlueprint::setup(const IIndexEnvironment &, const ParameterList ¶ms) { diff --git a/searchlib/src/vespa/searchlib/features/raw_score_feature.h b/searchlib/src/vespa/searchlib/features/raw_score_feature.h index 6344b527595..14106522d38 100644 --- a/searchlib/src/vespa/searchlib/features/raw_score_feature.h +++ b/searchlib/src/vespa/searchlib/features/raw_score_feature.h @@ -26,6 +26,7 @@ private: const fef::FieldInfo *_field; public: RawScoreBlueprint() : Blueprint("rawScore"), _field(0) {} + ~RawScoreBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment &, fef::IDumpFeatureVisitor &) const override {} fef::Blueprint::UP createInstance() const override { diff --git a/searchlib/src/vespa/searchlib/features/subqueries_feature.cpp b/searchlib/src/vespa/searchlib/features/subqueries_feature.cpp index 66a052ee0a2..779e14c8304 100644 --- a/searchlib/src/vespa/searchlib/features/subqueries_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/subqueries_feature.cpp @@ -44,6 +44,8 @@ SubqueriesExecutor::handle_bind_match_data(const fef::MatchData &md) //----------------------------------------------------------------------------- +SubqueriesBlueprint::~SubqueriesBlueprint() = default; + bool SubqueriesBlueprint::setup(const IIndexEnvironment &, const ParameterList ¶ms) { _field = params[0].asField(); diff --git a/searchlib/src/vespa/searchlib/features/subqueries_feature.h b/searchlib/src/vespa/searchlib/features/subqueries_feature.h index fefda9406bd..4637dfb2414 100644 --- a/searchlib/src/vespa/searchlib/features/subqueries_feature.h +++ b/searchlib/src/vespa/searchlib/features/subqueries_feature.h @@ -24,6 +24,7 @@ private: const fef::FieldInfo *_field; public: SubqueriesBlueprint() : Blueprint("subqueries"), _field(nullptr) {} + ~SubqueriesBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment &, fef::IDumpFeatureVisitor &) const override {} fef::Blueprint::UP createInstance() const override { return Blueprint::UP(new SubqueriesBlueprint); diff --git a/searchlib/src/vespa/searchlib/features/text_similarity_feature.cpp b/searchlib/src/vespa/searchlib/features/text_similarity_feature.cpp index 2723469aa67..495bb766e32 100644 --- a/searchlib/src/vespa/searchlib/features/text_similarity_feature.cpp +++ b/searchlib/src/vespa/searchlib/features/text_similarity_feature.cpp @@ -172,6 +172,8 @@ const vespalib::string TextSimilarityBlueprint::field_coverage_output("fieldCove TextSimilarityBlueprint::TextSimilarityBlueprint() : Blueprint("textSimilarity"), _field_id(fef::IllegalHandle) {} +TextSimilarityBlueprint::~TextSimilarityBlueprint() = default; + void TextSimilarityBlueprint::visitDumpFeatures(const fef::IIndexEnvironment &env, fef::IDumpFeatureVisitor &visitor) const diff --git a/searchlib/src/vespa/searchlib/features/text_similarity_feature.h b/searchlib/src/vespa/searchlib/features/text_similarity_feature.h index f7cd259b769..dddd8d89619 100644 --- a/searchlib/src/vespa/searchlib/features/text_similarity_feature.h +++ b/searchlib/src/vespa/searchlib/features/text_similarity_feature.h @@ -57,6 +57,7 @@ private: public: TextSimilarityBlueprint(); + ~TextSimilarityBlueprint() override; void visitDumpFeatures(const fef::IIndexEnvironment &env, fef::IDumpFeatureVisitor &visitor) const override; fef::Blueprint::UP createInstance() const override; fef::ParameterDescriptions getDescriptions() const override { diff --git a/searchlib/src/vespa/searchlib/fef/test/labels.cpp b/searchlib/src/vespa/searchlib/fef/test/labels.cpp index ee937600ac2..6e7c144cc7d 100644 --- a/searchlib/src/vespa/searchlib/fef/test/labels.cpp +++ b/searchlib/src/vespa/searchlib/fef/test/labels.cpp @@ -1,3 +1,9 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "labels.h" + +namespace search::fef::test { + +NoLabel::~NoLabel() = default; + +} diff --git a/searchlib/src/vespa/searchlib/fef/test/labels.h b/searchlib/src/vespa/searchlib/fef/test/labels.h index b76a145f922..5f27f786405 100644 --- a/searchlib/src/vespa/searchlib/fef/test/labels.h +++ b/searchlib/src/vespa/searchlib/fef/test/labels.h @@ -10,7 +10,8 @@ struct Labels { virtual ~Labels() {} }; struct NoLabel : public Labels { - virtual void inject(Properties &) const override {} + virtual void inject(Properties &) const override {} + ~NoLabel() override; }; struct SingleLabel : public Labels { vespalib::string label; diff --git a/searchlib/src/vespa/searchlib/query/tree/CMakeLists.txt b/searchlib/src/vespa/searchlib/query/tree/CMakeLists.txt index ec9156fbb52..4fcec251caa 100644 --- a/searchlib/src/vespa/searchlib/query/tree/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/query/tree/CMakeLists.txt @@ -5,6 +5,7 @@ vespa_add_library(searchlib_query_tree OBJECT intermediate.cpp intermediatenodes.cpp querybuilder.cpp + simplequery.cpp stackdumpcreator.cpp term.cpp location.cpp diff --git a/searchlib/src/vespa/searchlib/query/tree/simplequery.cpp b/searchlib/src/vespa/searchlib/query/tree/simplequery.cpp new file mode 100644 index 00000000000..cad97279b4c --- /dev/null +++ b/searchlib/src/vespa/searchlib/query/tree/simplequery.cpp @@ -0,0 +1,55 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "simplequery.h" + +namespace search::query { + +SimpleTrue::~SimpleTrue() = default; + +SimpleFalse::~SimpleFalse() = default; + +SimpleAnd::~SimpleAnd() = default; + +SimpleAndNot::~SimpleAndNot() = default; + +SimpleNear::~SimpleNear() = default; + +SimpleONear::~SimpleONear() = default; + +SimpleOr::~SimpleOr() = default; + +SimpleEquiv::~SimpleEquiv() = default; + +SimplePhrase::~SimplePhrase() = default; + +SimpleSameElement::~SimpleSameElement() = default; + +SimpleWeightedSetTerm::~SimpleWeightedSetTerm() = default; + +SimpleDotProduct::~SimpleDotProduct() = default; + +SimpleWandTerm::~SimpleWandTerm() = default; + +SimpleRank::~SimpleRank() = default; + +SimpleNumberTerm::~SimpleNumberTerm() = default; + +SimpleLocationTerm::~SimpleLocationTerm() = default; + +SimplePrefixTerm::~SimplePrefixTerm() = default; + +SimpleRangeTerm::~SimpleRangeTerm() = default; + +SimpleStringTerm::~SimpleStringTerm() = default; + +SimpleSubstringTerm::~SimpleSubstringTerm() = default; + +SimpleSuffixTerm::~SimpleSuffixTerm() = default; + +SimplePredicateQuery::~SimplePredicateQuery() = default; + +SimpleRegExpTerm::~SimpleRegExpTerm() = default; + +SimpleNearestNeighborTerm::~SimpleNearestNeighborTerm() = default; + +} diff --git a/searchlib/src/vespa/searchlib/query/tree/simplequery.h b/searchlib/src/vespa/searchlib/query/tree/simplequery.h index 0e52698c915..5047e072cb7 100644 --- a/searchlib/src/vespa/searchlib/query/tree/simplequery.h +++ b/searchlib/src/vespa/searchlib/query/tree/simplequery.h @@ -13,13 +13,30 @@ namespace search::query { -struct SimpleTrue : TrueQueryNode {}; -struct SimpleFalse : FalseQueryNode {}; -struct SimpleAnd : And {}; -struct SimpleAndNot : AndNot {}; -struct SimpleNear : Near { SimpleNear(size_t dist) : Near(dist) {} }; -struct SimpleONear : ONear { SimpleONear(size_t dist) : ONear(dist) {} }; -struct SimpleOr : Or {}; +struct SimpleTrue : TrueQueryNode { + ~SimpleTrue() override; +}; +struct SimpleFalse : FalseQueryNode { + ~SimpleFalse() override; +}; +struct SimpleAnd : And { + ~SimpleAnd() override; +}; +struct SimpleAndNot : AndNot { + ~SimpleAndNot() override; +}; +struct SimpleNear : Near { + SimpleNear(size_t dist) : Near(dist) {} + ~SimpleNear() override; +}; +struct SimpleONear : ONear { + SimpleONear(size_t dist) : ONear(dist) {} + ~SimpleONear() override; +}; +struct SimpleOr : Or +{ + ~SimpleOr() override; +}; struct SimpleWeakAnd : WeakAnd { SimpleWeakAnd(uint32_t minHits, vespalib::stringref view) : WeakAnd(minHits, view) @@ -28,70 +45,86 @@ struct SimpleWeakAnd : WeakAnd { struct SimpleEquiv : Equiv { SimpleEquiv(int32_t id, Weight weight) : Equiv(id, weight) {} + ~SimpleEquiv() override; }; struct SimplePhrase : Phrase { SimplePhrase(vespalib::stringref view, int32_t id, Weight weight) : Phrase(view, id, weight) {} + ~SimplePhrase() override; }; struct SimpleSameElement : SameElement { SimpleSameElement(vespalib::stringref view) : SameElement(view) {} + ~SimpleSameElement() override; }; struct SimpleWeightedSetTerm : WeightedSetTerm { SimpleWeightedSetTerm(uint32_t num_terms, vespalib::stringref view, int32_t id, Weight weight) : WeightedSetTerm(num_terms, view, id, weight) {} + ~SimpleWeightedSetTerm() override; }; struct SimpleDotProduct : DotProduct { SimpleDotProduct(uint32_t num_terms, vespalib::stringref view, int32_t id, Weight weight) : DotProduct(num_terms, view, id, weight) {} + ~SimpleDotProduct() override; }; struct SimpleWandTerm : WandTerm { SimpleWandTerm(uint32_t num_terms, vespalib::stringref view, int32_t id, Weight weight, uint32_t targetNumHits, int64_t scoreThreshold, double thresholdBoostFactor) : WandTerm(num_terms, view, id, weight, targetNumHits, scoreThreshold, thresholdBoostFactor) {} + ~SimpleWandTerm() override; +}; +struct SimpleRank : Rank +{ + ~SimpleRank() override; }; -struct SimpleRank : Rank {}; struct SimpleNumberTerm : NumberTerm { SimpleNumberTerm(Type term, vespalib::stringref view, int32_t id, Weight weight) : NumberTerm(term, view, id, weight) { } + ~SimpleNumberTerm() override; }; struct SimpleLocationTerm : LocationTerm { SimpleLocationTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : LocationTerm(term, view, id, weight) { } + ~SimpleLocationTerm() override; }; struct SimplePrefixTerm : PrefixTerm { SimplePrefixTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : PrefixTerm(term, view, id, weight) { } + ~SimplePrefixTerm() override; }; struct SimpleRangeTerm : RangeTerm { SimpleRangeTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : RangeTerm(term, view, id, weight) { } + ~SimpleRangeTerm() override; }; struct SimpleStringTerm : StringTerm { SimpleStringTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : StringTerm(term, view, id, weight) { } + ~SimpleStringTerm() override; }; struct SimpleSubstringTerm : SubstringTerm { SimpleSubstringTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : SubstringTerm(term, view, id, weight) { } + ~SimpleSubstringTerm() override; }; struct SimpleSuffixTerm : SuffixTerm { SimpleSuffixTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : SuffixTerm(term, view, id, weight) { } + ~SimpleSuffixTerm() override; }; struct SimplePredicateQuery : PredicateQuery { SimplePredicateQuery(PredicateQueryTerm::UP term, @@ -99,12 +132,14 @@ struct SimplePredicateQuery : PredicateQuery { int32_t id, Weight weight) : PredicateQuery(std::move(term), view, id, weight) { } + ~SimplePredicateQuery() override; }; struct SimpleRegExpTerm : RegExpTerm { SimpleRegExpTerm(const Type &term, vespalib::stringref view, int32_t id, Weight weight) : RegExpTerm(term, view, id, weight) { } + ~SimpleRegExpTerm() override; }; struct SimpleNearestNeighborTerm : NearestNeighborTerm { SimpleNearestNeighborTerm(vespalib::stringref query_tensor_name, vespalib::stringref field_name, @@ -115,6 +150,7 @@ struct SimpleNearestNeighborTerm : NearestNeighborTerm { target_num_hits, allow_approximate, explore_additional_hits, distance_threshold) {} + ~SimpleNearestNeighborTerm() override; }; diff --git a/searchlib/src/vespa/searchlib/queryeval/CMakeLists.txt b/searchlib/src/vespa/searchlib/queryeval/CMakeLists.txt index 214fb19b7ce..840f5b6b376 100644 --- a/searchlib/src/vespa/searchlib/queryeval/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/queryeval/CMakeLists.txt @@ -40,6 +40,7 @@ vespa_add_library(searchlib_queryeval OBJECT nearsearch.cpp nns_index_iterator.cpp orsearch.cpp + posting_info.cpp predicate_blueprint.cpp predicate_search.cpp ranksearch.cpp diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp index 997d3013971..79d78c3faab 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.cpp @@ -296,6 +296,8 @@ AndBlueprint::computeNextHitRate(const Blueprint & child, double hitRate) const //----------------------------------------------------------------------------- +OrBlueprint::~OrBlueprint() = default; + Blueprint::HitEstimate OrBlueprint::combine(const std::vector<HitEstimate> &data) const { diff --git a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h index b708ae3078e..c8bd26fe4a7 100644 --- a/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h +++ b/searchlib/src/vespa/searchlib/queryeval/intermediate_blueprints.h @@ -60,6 +60,7 @@ private: class OrBlueprint : public IntermediateBlueprint { public: + ~OrBlueprint() override; bool supports_termwise_children() const override { return true; } HitEstimate combine(const std::vector<HitEstimate> &data) const override; FieldSpecBaseList exposeFields() const override; diff --git a/searchlib/src/vespa/searchlib/queryeval/posting_info.cpp b/searchlib/src/vespa/searchlib/queryeval/posting_info.cpp new file mode 100644 index 00000000000..4b7b09b76c1 --- /dev/null +++ b/searchlib/src/vespa/searchlib/queryeval/posting_info.cpp @@ -0,0 +1,9 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "posting_info.h" + +namespace search::queryeval { + +MinMaxPostingInfo::~MinMaxPostingInfo() = default; + +} diff --git a/searchlib/src/vespa/searchlib/queryeval/posting_info.h b/searchlib/src/vespa/searchlib/queryeval/posting_info.h index 27c2eae56fb..c3fa5470e48 100644 --- a/searchlib/src/vespa/searchlib/queryeval/posting_info.h +++ b/searchlib/src/vespa/searchlib/queryeval/posting_info.h @@ -34,6 +34,7 @@ public: _minWeight(minWeight), _maxWeight(maxWeight) {} + ~MinMaxPostingInfo() override; int32_t getMinWeight() const { return _minWeight; } int32_t getMaxWeight() const { return _maxWeight; } }; diff --git a/searchlib/src/vespa/searchlib/queryeval/test/CMakeLists.txt b/searchlib/src/vespa/searchlib/queryeval/test/CMakeLists.txt index 925d0b9b6be..b3a19d7533e 100644 --- a/searchlib/src/vespa/searchlib/queryeval/test/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/queryeval/test/CMakeLists.txt @@ -1,5 +1,6 @@ # Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_library(searchlib_queryeval_test INTERFACE +vespa_add_library(searchlib_queryeval_test STATIC SOURCES + searchhistory.cpp DEPENDS ) diff --git a/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.cpp b/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.cpp new file mode 100644 index 00000000000..700b951d8ca --- /dev/null +++ b/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.cpp @@ -0,0 +1,11 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "searchhistory.h" + +namespace search::queryeval::test { + +SearchHistory::Entry::Entry(const Entry&) = default; + +SearchHistory::Entry& SearchHistory::Entry::operator=(const Entry&) = default; + +} diff --git a/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.h b/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.h index 17e3cc49444..9b31577cd9c 100644 --- a/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.h +++ b/searchlib/src/vespa/searchlib/queryeval/test/searchhistory.h @@ -17,7 +17,11 @@ struct SearchHistory { uint32_t docid; Entry(const std::string &t, const std::string &o, uint32_t id) : target(t), op(o), docid(id) {} + Entry(const Entry&); + Entry(Entry&&) noexcept = default; ~Entry() {} + Entry& operator=(const Entry&); + Entry& operator=(Entry&&) noexcept = default; bool operator==(const Entry &rhs) const { return ((target == rhs.target) && (op == rhs.op) && diff --git a/slobrok/src/vespa/slobrok/server/service_map_history.cpp b/slobrok/src/vespa/slobrok/server/service_map_history.cpp index 3303f364515..7ddbce899d5 100644 --- a/slobrok/src/vespa/slobrok/server/service_map_history.cpp +++ b/slobrok/src/vespa/slobrok/server/service_map_history.cpp @@ -70,7 +70,7 @@ void ServiceMapHistory::asyncGenerationDiff(DiffCompletionHandler *handler, cons } bool ServiceMapHistory::cancel(DiffCompletionHandler *handler) { - size_t removed = std::erase_if(_waitList, [=](const Waiter &elem){ return elem.first == handler; }); + size_t removed = std::erase_if(_waitList, [=](const Waiter &elem) noexcept { return elem.first == handler; }); return (removed > 0); } diff --git a/slobrok/src/vespa/slobrok/server/union_service_map.cpp b/slobrok/src/vespa/slobrok/server/union_service_map.cpp index fc8b0cbcdfd..5a55299770a 100644 --- a/slobrok/src/vespa/slobrok/server/union_service_map.cpp +++ b/slobrok/src/vespa/slobrok/server/union_service_map.cpp @@ -83,7 +83,7 @@ void UnionServiceMap::remove(const ServiceMapping &mapping) return; } size_t old_size = values.size(); - std::erase_if(values, [] (const CountedSpec &v) { return v.count == 0; }); + std::erase_if(values, [] (const CountedSpec &v) noexcept { return v.count == 0; }); if (values.size() == 1u) { LOG_ASSERT(old_size == 2u); ServiceMapping toAdd{key, values[0].spec}; diff --git a/staging_vespalib/src/tests/state_server/state_server_test.cpp b/staging_vespalib/src/tests/state_server/state_server_test.cpp index a7b72cd505e..5903970b740 100644 --- a/staging_vespalib/src/tests/state_server/state_server_test.cpp +++ b/staging_vespalib/src/tests/state_server/state_server_test.cpp @@ -117,6 +117,7 @@ TEST_FFFF("require that handler is selected based on longest matching url prefix } struct EchoHost : JsonGetHandler { + ~EchoHost() override; vespalib::string get(const vespalib::string &host, const vespalib::string &, const std::map<vespalib::string,vespalib::string> &) const override { @@ -124,6 +125,8 @@ struct EchoHost : JsonGetHandler { } }; +EchoHost::~EchoHost() = default; + TEST_FF("require that host is passed correctly", EchoHost(), HttpServer(0)) { auto token = f2.repo().bind(my_path, f1); EXPECT_EQUAL(make_string("%s:%d", HostName::get().c_str(), f2.port()), f2.host()); @@ -140,6 +143,7 @@ struct SamplingHandler : JsonGetHandler { mutable vespalib::string my_host; mutable vespalib::string my_path; mutable std::map<vespalib::string,vespalib::string> my_params; + ~SamplingHandler() override; vespalib::string get(const vespalib::string &host, const vespalib::string &path, const std::map<vespalib::string,vespalib::string> ¶ms) const override { @@ -153,6 +157,8 @@ struct SamplingHandler : JsonGetHandler { } }; +SamplingHandler::~SamplingHandler() = default; + TEST_FF("require that request parameters can be inspected", SamplingHandler(), HttpServer(0)) { auto token = f2.repo().bind("/foo", f1); @@ -361,6 +367,7 @@ TEST_FFFFF("require that custom handlers can be added to the state server", } struct EchoConsumer : MetricsProducer { + ~EchoConsumer() override; vespalib::string getMetrics(const vespalib::string &consumer) override { return "[\"" + consumer + "\"]"; } @@ -369,6 +376,8 @@ struct EchoConsumer : MetricsProducer { } }; +EchoConsumer::~EchoConsumer() = default; + TEST_FFFF("require that empty v1 metrics consumer defaults to 'statereporter'", SimpleHealthProducer(), EchoConsumer(), SimpleComponentConfigProducer(), StateApi(f1, f2, f3)) diff --git a/staging_vespalib/src/tests/stllike/lrucache.cpp b/staging_vespalib/src/tests/stllike/lrucache.cpp index a23fec26448..2cc6f2b4ee8 100644 --- a/staging_vespalib/src/tests/stllike/lrucache.cpp +++ b/staging_vespalib/src/tests/stllike/lrucache.cpp @@ -90,7 +90,7 @@ TEST("testCache") { typedef std::shared_ptr<std::string> MyKey; typedef std::shared_ptr<std::string> MyData; -struct SharedEqual : public std::binary_function<MyKey, MyKey, bool> { +struct SharedEqual { bool operator()(const MyKey & a, const MyKey & b) { return ((*a) == (*b)); } diff --git a/staging_vespalib/src/tests/xmlserializable/xmlserializabletest.cpp b/staging_vespalib/src/tests/xmlserializable/xmlserializabletest.cpp index 4ea3eb2fff2..cc8d61cb7c2 100644 --- a/staging_vespalib/src/tests/xmlserializable/xmlserializabletest.cpp +++ b/staging_vespalib/src/tests/xmlserializable/xmlserializabletest.cpp @@ -43,11 +43,11 @@ Test::testNormalUsage() << XmlEndTag() << XmlEndTag(); std::string expected = - "\n<car>\n" + "<car>\n" "<door windowstate=\"up\"/>\n" "<description>This is a car description used to test</description>\n" "</car>"; - EXPECT_EQUAL(expected, "\n" + ost.str()); + EXPECT_EQUAL(expected, ost.str()); } void @@ -76,14 +76,14 @@ Test::testEscaping() << XmlEndTag() << XmlEndTag(); std::string expected = - "\n<__trash_->\n" + "<__trash_->\n" "<foo bar=\"<100%" & >\"/>\n" "<escaped><>&\"'% \n	�</escaped>\n" "<encoded binaryencoding=\"base64\">PD4mIiclIAkMAA==</encoded>\n" "<auto1><>&	 \nfoo</auto1>\n" "<auto2 binaryencoding=\"base64\">PD4mCQANCmZvbw==</auto2>\n" "</__trash_->"; - EXPECT_EQUAL(expected, "\n" + ost.str()); + EXPECT_EQUAL(expected, ost.str()); } namespace { @@ -118,7 +118,7 @@ Test::testNesting() << XmlEndTag() << XmlEndTag(); std::string expected = - "\n<car>\n" + "<car>\n" "<door color=\"blue\">\n" "<other count=\"5\">\n" "<something>foo</something>\n" @@ -127,7 +127,7 @@ Test::testNesting() "</door>\n" "<description>This is a car description used to test</description>\n" "</car>"; - EXPECT_EQUAL(expected, "\n" + ost.str()); + EXPECT_EQUAL(expected, ost.str()); } void @@ -146,7 +146,7 @@ Test::testIndent() << XmlEndTag() << XmlEndTag() << XmlEndTag(); - std::string expected = "\n" + std::string expected = "<foo>\n" " <bar>2.14</bar>\n" " Litt innhold\n" @@ -155,7 +155,7 @@ Test::testIndent() " <base binaryencoding=\"base64\">Zm9vYmFy</base>\n" " </nytag>\n" "</foo>"; - EXPECT_EQUAL(expected, "\n" + ost.str()); + EXPECT_EQUAL(expected, ost.str()); } } // vespalib diff --git a/staging_vespalib/src/vespa/vespalib/util/programoptions.cpp b/staging_vespalib/src/vespa/vespalib/util/programoptions.cpp index 80381d494df..9ea7c1648d1 100644 --- a/staging_vespalib/src/vespa/vespalib/util/programoptions.cpp +++ b/staging_vespalib/src/vespa/vespalib/util/programoptions.cpp @@ -56,6 +56,10 @@ void ProgramOptions::NumberOptionParser<Number>::set(const std::vector<std::stri } } +ProgramOptions::FlagOptionParser::~FlagOptionParser() = default; + +ProgramOptions::StringOptionParser::~StringOptionParser() = default; + ProgramOptions::OptionParser::OptionParser( const std::string& nameList, uint32_t argCount, const std::string& desc) : _names(splitString(nameList, ' ')), diff --git a/staging_vespalib/src/vespa/vespalib/util/programoptions.h b/staging_vespalib/src/vespa/vespalib/util/programoptions.h index 0bd3eb7c3c9..0c75f9b2c72 100644 --- a/staging_vespalib/src/vespa/vespalib/util/programoptions.h +++ b/staging_vespalib/src/vespa/vespalib/util/programoptions.h @@ -262,6 +262,7 @@ struct ProgramOptions::NumberOptionParser : public OptionParser { _number(number), _defaultValue(defValue) {} + ~NumberOptionParser() override; void set(const std::vector<std::string>& arguments) override; void setDefault() override { _number = _defaultValue; } @@ -270,6 +271,9 @@ struct ProgramOptions::NumberOptionParser : public OptionParser { } }; +template<typename Number> +ProgramOptions::NumberOptionParser<Number>::~NumberOptionParser() = default; + struct ProgramOptions::BoolOptionParser : public OptionParser { bool& _value; bool _defaultValue; @@ -285,10 +289,12 @@ struct ProgramOptions::FlagOptionParser : public OptionParser { FlagOptionParser(const std::string& nameList, bool& value, const std::string& description); FlagOptionParser(const std::string& nameList, bool& value, const bool& unsetValue, const std::string& description); + ~FlagOptionParser() override; void set(const std::vector<std::string>&) override { _value = !_unsetValue; } void setDefault() override { _value = _unsetValue; } }; + struct ProgramOptions::StringOptionParser : public OptionParser { std::string& _value; std::string _defaultValue; @@ -296,6 +302,7 @@ struct ProgramOptions::StringOptionParser : public OptionParser { StringOptionParser(const std::string& nameList, std::string& value, const std::string& description); StringOptionParser(const std::string& nameList, std::string& value, const std::string& defVal, const std::string& desc); + ~StringOptionParser() override; void set(const std::vector<std::string>& arguments) override { _value = arguments[0]; } void setDefault() override { _value = _defaultValue; } diff --git a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp index baed51663f8..407bef5f8bc 100644 --- a/storage/src/tests/persistence/filestorage/filestormanagertest.cpp +++ b/storage/src/tests/persistence/filestorage/filestormanagertest.cpp @@ -284,19 +284,21 @@ struct FileStorHandlerComponents { FileStorHandlerComponents::~FileStorHandlerComponents() = default; struct PersistenceHandlerComponents : public FileStorHandlerComponents { + vespalib::ISequencedTaskExecutor& executor; ServiceLayerComponent component; BucketOwnershipNotifier bucketOwnershipNotifier; std::unique_ptr<PersistenceHandler> persistenceHandler; PersistenceHandlerComponents(FileStorTestBase& test) : FileStorHandlerComponents(test), + executor(test._node->executor()), component(test._node->getComponentRegister(), "test"), bucketOwnershipNotifier(component, messageSender), persistenceHandler() { vespa::config::content::StorFilestorConfig cfg; persistenceHandler = - std::make_unique<PersistenceHandler>(test._node->executor(), component, cfg, + std::make_unique<PersistenceHandler>(executor, component, cfg, test._node->getPersistenceProvider(), *filestorHandler, bucketOwnershipNotifier, *metrics.disk->threads[0]); @@ -307,7 +309,12 @@ struct PersistenceHandlerComponents : public FileStorHandlerComponents { } }; -PersistenceHandlerComponents::~PersistenceHandlerComponents() = default; +PersistenceHandlerComponents::~PersistenceHandlerComponents() +{ + // Ensure any pending tasks have completed before destroying any resources they + // may implicitly depend on. + executor.sync_all(); +} } @@ -811,6 +818,8 @@ TEST_F(FileStorManagerTest, priority) { // Closing file stor handler before threads are deleted, such that // file stor threads getNextMessage calls returns. filestorHandler.close(); + // Sync any tasks that may be pending for the handlers on the stack. + _node->executor().sync_all(); } TEST_F(FileStorManagerTest, split1) { diff --git a/storage/src/vespa/storage/persistence/asynchandler.cpp b/storage/src/vespa/storage/persistence/asynchandler.cpp index d80eb140eec..a55889652a8 100644 --- a/storage/src/vespa/storage/persistence/asynchandler.cpp +++ b/storage/src/vespa/storage/persistence/asynchandler.cpp @@ -86,6 +86,7 @@ public: _executorId(executor.getExecutorId(bucketId.getId())) { } + ~ResultTaskOperationDone() override; void onComplete(spi::Result::UP result) noexcept override { _task->setResult(std::move(result)); _executor.executeTask(_executorId, std::move(_task)); @@ -99,6 +100,8 @@ private: vespalib::ISequencedTaskExecutor::ExecutorId _executorId; }; +ResultTaskOperationDone::~ResultTaskOperationDone() = default; + bool bucketStatesAreSemanticallyEqual(const api::BucketInfo& a, const api::BucketInfo& b) { // Don't check document sizes, as background moving of documents in Proton diff --git a/storageapi/src/vespa/storageapi/message/bucket.cpp b/storageapi/src/vespa/storageapi/message/bucket.cpp index 04a40fbc885..520f1aa2741 100644 --- a/storageapi/src/vespa/storageapi/message/bucket.cpp +++ b/storageapi/src/vespa/storageapi/message/bucket.cpp @@ -475,6 +475,8 @@ RequestBucketInfoCommand::RequestBucketInfoCommand( { } +RequestBucketInfoCommand::~RequestBucketInfoCommand() = default; + document::Bucket RequestBucketInfoCommand::getBucket() const { diff --git a/storageapi/src/vespa/storageapi/message/bucket.h b/storageapi/src/vespa/storageapi/message/bucket.h index 5fd79ffffea..47785a92039 100644 --- a/storageapi/src/vespa/storageapi/message/bucket.h +++ b/storageapi/src/vespa/storageapi/message/bucket.h @@ -354,6 +354,7 @@ public: RequestBucketInfoCommand(document::BucketSpace bucketSpace, uint16_t distributor, const lib::ClusterState& state); + ~RequestBucketInfoCommand() override; const std::vector<document::BucketId>& getBuckets() const { return _buckets; } diff --git a/vbench/src/tests/dispatcher/dispatcher_test.cpp b/vbench/src/tests/dispatcher/dispatcher_test.cpp index 618940aab57..85879feb0ee 100644 --- a/vbench/src/tests/dispatcher/dispatcher_test.cpp +++ b/vbench/src/tests/dispatcher/dispatcher_test.cpp @@ -7,9 +7,12 @@ using namespace vbench; struct MyHandler : public Handler<int> { int value; MyHandler() : value(-1) {} + ~MyHandler() override; void handle(std::unique_ptr<int> v) override { value = (v.get() != 0) ? *v : 0; } }; +MyHandler::~MyHandler() = default; + struct Fetcher : public vespalib::Runnable { Provider<int> &provider; Handler<int> &handler; diff --git a/vbench/src/vbench/test/request_receptor.cpp b/vbench/src/vbench/test/request_receptor.cpp index 33c9bf5ad57..1da96efa6aa 100644 --- a/vbench/src/vbench/test/request_receptor.cpp +++ b/vbench/src/vbench/test/request_receptor.cpp @@ -4,6 +4,8 @@ namespace vbench { +RequestReceptor::~RequestReceptor() = default; + void RequestReceptor::handle(Request::UP req) { diff --git a/vbench/src/vbench/test/request_receptor.h b/vbench/src/vbench/test/request_receptor.h index 15262b64906..dc62ca21066 100644 --- a/vbench/src/vbench/test/request_receptor.h +++ b/vbench/src/vbench/test/request_receptor.h @@ -10,6 +10,7 @@ namespace vbench { struct RequestReceptor : public Handler<Request> { Request::UP request; RequestReceptor() : request() {} + ~RequestReceptor() override; void handle(Request::UP req) override; }; diff --git a/vbench/src/vbench/vbench/latency_analyzer.cpp b/vbench/src/vbench/vbench/latency_analyzer.cpp index f5514d988c5..c2892bbbaf8 100644 --- a/vbench/src/vbench/vbench/latency_analyzer.cpp +++ b/vbench/src/vbench/vbench/latency_analyzer.cpp @@ -52,6 +52,8 @@ LatencyAnalyzer::LatencyAnalyzer(Handler<Request> &next) { } +LatencyAnalyzer::~LatencyAnalyzer() = default; + void LatencyAnalyzer::handle(Request::UP request) { diff --git a/vbench/src/vbench/vbench/latency_analyzer.h b/vbench/src/vbench/vbench/latency_analyzer.h index fac1be5ef4d..8701eea5b38 100644 --- a/vbench/src/vbench/vbench/latency_analyzer.h +++ b/vbench/src/vbench/vbench/latency_analyzer.h @@ -35,6 +35,7 @@ public: string toString() const; }; LatencyAnalyzer(Handler<Request> &next); + ~LatencyAnalyzer() override; void handle(Request::UP request) override; void report() override; void addLatency(double latency); diff --git a/vbench/src/vbench/vbench/request_generator.cpp b/vbench/src/vbench/vbench/request_generator.cpp index 9b475b00fc6..b9061349ab3 100644 --- a/vbench/src/vbench/vbench/request_generator.cpp +++ b/vbench/src/vbench/vbench/request_generator.cpp @@ -12,6 +12,8 @@ RequestGenerator::RequestGenerator(const string &inputFile, { } +RequestGenerator::~RequestGenerator() = default; + void RequestGenerator::abort() { diff --git a/vbench/src/vbench/vbench/request_generator.h b/vbench/src/vbench/vbench/request_generator.h index d088edafd33..fef3471a427 100644 --- a/vbench/src/vbench/vbench/request_generator.h +++ b/vbench/src/vbench/vbench/request_generator.h @@ -22,6 +22,7 @@ private: public: RequestGenerator(const string &inputFile, Handler<Request> &next); + ~RequestGenerator() override; void abort() override; void run() override; const Taint &tainted() const override { return _input.tainted(); } diff --git a/vdslib/src/vespa/vdslib/container/documentsummary.h b/vdslib/src/vespa/vdslib/container/documentsummary.h index bbfeb684559..8bb70640d5f 100644 --- a/vdslib/src/vespa/vdslib/container/documentsummary.h +++ b/vdslib/src/vespa/vdslib/container/documentsummary.h @@ -46,7 +46,7 @@ private: uint32_t _summaryOffset; uint32_t _summaryLen; }; - class Compare : public std::binary_function<Summary, Summary, bool> { + class Compare { private: const char * _buffer; public: diff --git a/vdslib/src/vespa/vdslib/container/searchresult.h b/vdslib/src/vespa/vdslib/container/searchresult.h index a777a4731e6..cb61926253f 100644 --- a/vdslib/src/vespa/vdslib/container/searchresult.h +++ b/vdslib/src/vespa/vdslib/container/searchresult.h @@ -99,7 +99,7 @@ private: uint32_t _docIdOffset; uint32_t _index; // refers to sortBlob }; - class SortDataCompare : public std::binary_function<Hit, Hit, bool> { + class SortDataCompare { private: const BlobContainer & _sortBlob; public: diff --git a/vdslib/src/vespa/vdslib/distribution/distribution.cpp b/vdslib/src/vespa/vdslib/distribution/distribution.cpp index 8a8d273e9db..582839158ef 100644 --- a/vdslib/src/vespa/vdslib/distribution/distribution.cpp +++ b/vdslib/src/vespa/vdslib/distribution/distribution.cpp @@ -10,6 +10,7 @@ #include <vespa/config/print/asciiconfigreader.hpp> #include <vespa/vespalib/util/exceptions.h> #include <vespa/config-stor-distribution.h> +#include <algorithm> #include <cmath> #include <cassert> diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java index 4d7c2f1cc14..10e55527a2a 100644 --- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java +++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.google.inject.Inject; import com.yahoo.cloud.config.ClusterListConfig; import com.yahoo.concurrent.DaemonThreadFactory; +import com.yahoo.concurrent.SystemTimer; import com.yahoo.container.core.HandlerMetricContextUtil; import com.yahoo.container.core.documentapi.VespaDocumentAccess; import com.yahoo.container.jdisc.ContentChannelOutputStream; @@ -20,7 +21,6 @@ import com.yahoo.document.FixedBucketSpaces; import com.yahoo.document.TestAndSetCondition; import com.yahoo.document.config.DocumentmanagerConfig; import com.yahoo.document.fieldset.AllFields; -import com.yahoo.document.fieldset.DocumentOnly; import com.yahoo.document.fieldset.DocIdOnly; import com.yahoo.document.idstring.IdIdString; import com.yahoo.document.json.DocumentOperationType; @@ -212,14 +212,11 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler { this.asyncSession = access.createAsyncSession(new AsyncParameters()); this.clusters = parseClusters(clusterListConfig, bucketSpacesConfig); this.operations = new ConcurrentLinkedDeque<>(); - this.dispatcher.scheduleWithFixedDelay(this::dispatchEnqueued, - executorConfig.resendDelayMillis(), - executorConfig.resendDelayMillis(), - MILLISECONDS); - this.visitDispatcher.scheduleWithFixedDelay(this::dispatchVisitEnqueued, - executorConfig.resendDelayMillis(), - executorConfig.resendDelayMillis(), - MILLISECONDS); + long resendDelayMS = SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(executorConfig.resendDelayMillis())).toMillis(); + + //TODO Here it would be better do have dedicated threads with different wait depending on blocked or empty. + this.dispatcher.scheduleWithFixedDelay(this::dispatchEnqueued, resendDelayMS, resendDelayMS, MILLISECONDS); + this.visitDispatcher.scheduleWithFixedDelay(this::dispatchVisitEnqueued, resendDelayMS, resendDelayMS, MILLISECONDS); } // ------------------------------------------------ Requests ------------------------------------------------- diff --git a/vespajlib/src/main/java/com/yahoo/concurrent/SystemTimer.java b/vespajlib/src/main/java/com/yahoo/concurrent/SystemTimer.java index ecaae5e6387..8111d52a10f 100644 --- a/vespajlib/src/main/java/com/yahoo/concurrent/SystemTimer.java +++ b/vespajlib/src/main/java/com/yahoo/concurrent/SystemTimer.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.concurrent; +import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -16,10 +17,10 @@ public enum SystemTimer implements Timer { private volatile long millis; - public static int detectHz() { + public static long detectHz() { Logger log = Logger.getLogger(SystemTimer.class.getName()); String hzEnv = System.getenv("VESPA_TIMER_HZ"); - int hz = 1000; + long hz = 1000; if ((hzEnv != null) && !hzEnv.isBlank()) { try { hz = Integer.parseInt(hzEnv); @@ -32,8 +33,15 @@ public enum SystemTimer implements Timer { return hz; } + public static Duration adjustTimeoutByDetectedHz(Duration timeout) { + return adjustTimeoutByDetectedHz(timeout, detectHz()); + } + public static Duration adjustTimeoutByDetectedHz(Duration timeout, long hz) { + return timeout.multipliedBy(1000).dividedBy(hz); + } + SystemTimer() { - int napTime = 1000 / detectHz(); + long napTime = adjustTimeoutByDetectedHz(Duration.ofMillis(1)).toMillis(); millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); Thread thread = new Thread() { diff --git a/vespajlib/src/test/java/com/yahoo/concurrent/ExecutorsTestCase.java b/vespajlib/src/test/java/com/yahoo/concurrent/ExecutorsTestCase.java index 707445efc5b..0a1bdc51930 100644 --- a/vespajlib/src/test/java/com/yahoo/concurrent/ExecutorsTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/concurrent/ExecutorsTestCase.java @@ -8,8 +8,16 @@ import static org.junit.Assert.assertTrue; import org.junit.Ignore; import org.junit.Test; +import java.time.Duration; import java.util.LinkedList; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class ExecutorsTestCase { @@ -137,4 +145,21 @@ public class ExecutorsTestCase { assertEquals(9, measureMaxNumThreadsUsage(new ThreadPoolExecutor(100, 100, 0L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(false)), 3000, 10)); Runner.threadCount.set(0); } + + @Test + public void requireHzAndAdjustment() { + assertEquals(1000, SystemTimer.detectHz()); + + assertEquals(1, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(1)).toMillis()); + assertEquals(20, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(20)).toMillis()); + + assertEquals(1, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(1), 1000).toMillis()); + assertEquals(10, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(1), 100).toMillis()); + assertEquals(100, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(1), 10).toMillis()); + + assertEquals(20, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(20), 1000).toMillis()); + assertEquals(200, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(20), 100).toMillis()); + assertEquals(2000, SystemTimer.adjustTimeoutByDetectedHz(Duration.ofMillis(20), 10).toMillis()); + } + } diff --git a/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp b/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp index 6e8e6e5f761..739f036fb5c 100644 --- a/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp +++ b/vespalib/src/tests/net/async_resolver/async_resolver_test.cpp @@ -22,12 +22,15 @@ struct MyClock : public AsyncResolver::Clock { using time_point = AsyncResolver::time_point; using seconds = AsyncResolver::seconds; time_point my_now; + ~MyClock() override; void set_now(seconds t) { my_now = time_point(std::chrono::duration_cast<time_point::duration>(t)); } AsyncResolver::time_point now() override { return my_now; } }; +MyClock::~MyClock() = default; + struct BlockingHostResolver : public AsyncResolver::HostResolver { CountDownLatch callers; Gate barrier; diff --git a/vespalib/src/tests/rendezvous/rendezvous_test.cpp b/vespalib/src/tests/rendezvous/rendezvous_test.cpp index 616824af7f1..11bcf62d77e 100644 --- a/vespalib/src/tests/rendezvous/rendezvous_test.cpp +++ b/vespalib/src/tests/rendezvous/rendezvous_test.cpp @@ -15,6 +15,7 @@ struct Value { template <typename T, bool ext_id> struct Empty : Rendezvous<int, T, ext_id> { Empty(size_t n) : Rendezvous<int, T, ext_id>(n) {} + ~Empty() override; void mingle() override {} T meet(size_t thread_id) { if constexpr (ext_id) { @@ -26,6 +27,9 @@ struct Empty : Rendezvous<int, T, ext_id> { } }; +template <typename T, bool ext_id> +Empty<T, ext_id>::~Empty() = default; + template <bool ext_id> struct Add : Rendezvous<size_t, std::pair<size_t, size_t>, ext_id> { using Super = Rendezvous<size_t, std::pair<size_t, size_t>, ext_id>; @@ -33,6 +37,7 @@ struct Add : Rendezvous<size_t, std::pair<size_t, size_t>, ext_id> { using Super::in; using Super::out; Add(size_t n) : Super(n) {} + ~Add() override; void mingle() override { size_t sum = 0; for (size_t i = 0; i < size(); ++i) { @@ -45,12 +50,16 @@ struct Add : Rendezvous<size_t, std::pair<size_t, size_t>, ext_id> { }; template <bool ext_id> +Add<ext_id>::~Add() = default; + +template <bool ext_id> struct Modify : Rendezvous<size_t, size_t, ext_id> { using Super = Rendezvous<size_t, size_t, ext_id>; using Super::size; using Super::in; using Super::out; Modify(size_t n) : Super(n) {} + ~Modify() override; void mingle() override { for (size_t i = 0; i < size(); ++i) { in(i) += 1; @@ -61,6 +70,9 @@ struct Modify : Rendezvous<size_t, size_t, ext_id> { } }; +template <bool ext_id> +Modify<ext_id>::~Modify() = default; + template <typename T, bool ext_id> struct Swap : Rendezvous<T, T, ext_id> { using Super = Rendezvous<T, T, ext_id>; @@ -68,12 +80,16 @@ struct Swap : Rendezvous<T, T, ext_id> { using Super::in; using Super::out; Swap() : Super(2) {} + ~Swap() override; void mingle() override { out(0) = std::move(in(1)); out(1) = std::move(in(0)); } }; +template <typename T, bool ext_id> +Swap<T, ext_id>::~Swap() = default; + template <bool ext_id> struct DetectId : Rendezvous<int, size_t, ext_id> { using Super = Rendezvous<int, size_t, ext_id>; @@ -81,6 +97,7 @@ struct DetectId : Rendezvous<int, size_t, ext_id> { using Super::in; using Super::out; DetectId(size_t n) : Super(n) {} + ~DetectId() override; void mingle() override { for (size_t i = 0; i < size(); ++i) { out(i) = i; @@ -96,8 +113,12 @@ struct DetectId : Rendezvous<int, size_t, ext_id> { } }; +template <bool ext_id> +DetectId<ext_id>::~DetectId() = default; + struct Any : Rendezvous<bool, bool> { Any(size_t n) : Rendezvous<bool, bool>(n) {} + ~Any() override; void mingle() override { bool result = false; for (size_t i = 0; i < size(); ++i) { @@ -110,6 +131,8 @@ struct Any : Rendezvous<bool, bool> { bool check(bool flag) { return this->rendezvous(flag); } }; +Any::~Any() = default; + TEST("require that creating an empty rendezvous will fail") { EXPECT_EXCEPTION(Add<false>(0), IllegalArgumentException, ""); EXPECT_EXCEPTION(Add<true>(0), IllegalArgumentException, ""); diff --git a/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp b/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp index 8d5d393fe22..5d69a18112a 100644 --- a/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp +++ b/vespalib/src/tests/simple_thread_bundle/simple_thread_bundle_test.cpp @@ -37,12 +37,15 @@ struct State { struct Blocker : Runnable { Gate start; + ~Blocker() override; void run() override { start.await(); } Gate done; // set externally }; +Blocker::~Blocker() = default; + TEST_MT_FF("require that signals can be counted and cancelled", 2, Signal, size_t(16000)) { if (thread_id == 0) { for (size_t i = 0; i < f2; ++i) { diff --git a/vespalib/src/tests/stllike/hash_test.cpp b/vespalib/src/tests/stllike/hash_test.cpp index 5cba6f73e10..c530bbdb14a 100644 --- a/vespalib/src/tests/stllike/hash_test.cpp +++ b/vespalib/src/tests/stllike/hash_test.cpp @@ -455,8 +455,8 @@ class WrappedKey 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; } + size_t hash() const noexcept { return vespalib::hash<int>()(*_key); } + bool operator==(const WrappedKey &rhs) const noexcept { return *_key == *rhs._key; } }; } diff --git a/vespalib/src/tests/stllike/hashtable_test.cpp b/vespalib/src/tests/stllike/hashtable_test.cpp index 74490e413d1..ccb1136729e 100644 --- a/vespalib/src/tests/stllike/hashtable_test.cpp +++ b/vespalib/src/tests/stllike/hashtable_test.cpp @@ -17,7 +17,7 @@ using namespace vespalib; namespace { template<typename T> -struct Dereference : std::unary_function<T, std::unique_ptr<T>> { +struct Dereference { T &operator()(std::unique_ptr<T>& p) const { return *p; } const T& operator()(const std::unique_ptr<T>& p) const { return *p; } }; @@ -119,7 +119,7 @@ TEST("require that you can insert duplicates") { } template<typename To, typename Vector> -struct FirstInVector : std::unary_function<To, Vector> { +struct FirstInVector { To &operator()(Vector& v) const { return v[0]; } const To& operator()(const Vector& v) const { return v[0]; } }; diff --git a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp index 86c3dc1411c..7b9dfc98fa5 100644 --- a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp +++ b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp @@ -92,7 +92,7 @@ private: Gid _gid; }; -struct IndirectCmp : public std::binary_function<Slot*, Slot*, bool> { +struct IndirectCmp { bool operator() (const Slot* s1, const Slot* s2) noexcept { return s1->cmp(*s2) < 0; } diff --git a/vespalib/src/tests/testapp-debug/debugtest.cpp b/vespalib/src/tests/testapp-debug/debugtest.cpp index 2ff7affc323..78bf3d69215 100644 --- a/vespalib/src/tests/testapp-debug/debugtest.cpp +++ b/vespalib/src/tests/testapp-debug/debugtest.cpp @@ -5,25 +5,25 @@ using namespace vespalib; void testDebug() { TEST_DEBUG("lhs.out", "rhs.out"); - EXPECT_EQUAL("a\n" - "b\n" - "c\n", + EXPECT_EQUAL(string("a\n" + "b\n" + "c\n"), - "a\n" - "b\n" - "c\n" - "d\n"); - EXPECT_EQUAL("a\n" - "d\n" - "b\n" - "c\n", + string("a\n" + "b\n" + "c\n" + "d\n")); + EXPECT_EQUAL(string("a\n" + "d\n" + "b\n" + "c\n"), - "a\n" - "b\n" - "c\n" - "d\n"); + string("a\n" + "b\n" + "c\n" + "d\n")); EXPECT_EQUAL(1, 2); - EXPECT_EQUAL("foo", "bar"); + EXPECT_EQUAL(string("foo"), string("bar")); } TEST_MAIN() { diff --git a/vespalib/src/vespa/vespalib/btree/btreebuilder.hpp b/vespalib/src/vespa/vespalib/btree/btreebuilder.hpp index 5abe2b2cebd..3162dfb4820 100644 --- a/vespalib/src/vespa/vespalib/btree/btreebuilder.hpp +++ b/vespalib/src/vespa/vespalib/btree/btreebuilder.hpp @@ -106,10 +106,10 @@ normalize() /* Adjust validLeaves for rightmost nodes */ for (level = 0; level < _inodes.size(); level++) { InternalNodeType *inode = _inodes[level].data; - NodeRef lcRef(inode->getLastChild()); + NodeRef lcRef(inode->get_last_child_relaxed()); assert(NodeAllocatorType::isValidRef(lcRef)); assert((level == 0) == _allocator.isLeafRef(lcRef)); - inode->incValidLeaves(_allocator.validLeaves(inode->getLastChild())); + inode->incValidLeaves(_allocator.validLeaves(inode->get_last_child_relaxed())); inode->update(inode->validSlots() - 1, level == 0 ? _allocator.mapLeafRef(lcRef)->getLastKey() : @@ -134,10 +134,10 @@ normalize() inode = _allocator.mapInternalRef(iRef); assert(inode != nullptr); assert(inode->validSlots() >= 1); - child = inode->getLastChild(); + child = inode->get_last_child_relaxed(); } else { /* Use next to last child of rightmost node on level */ - child = inode->getChild(inode->validSlots() - 2); + child = inode->get_child_relaxed(inode->validSlots() - 2); } if (level == 0) break; @@ -190,11 +190,11 @@ normalize() } if (pnode->validSlots() > 0) { uint32_t s = pnode->validSlots() - 1; - LeafNodeType *l = _allocator.mapLeafRef(pnode->getChild(s)); + LeafNodeType *l = _allocator.mapLeafRef(pnode->get_child_relaxed(s)); pnode->writeKey(s, l->getLastKey()); if (s > 0) { --s; - l = _allocator.mapLeafRef(pnode->getChild(s)); + l = _allocator.mapLeafRef(pnode->get_child_relaxed(s)); pnode->writeKey(s, l->getLastKey()); } } @@ -202,7 +202,7 @@ normalize() InternalNodeType *lpnode = _allocator.mapInternalRef(leftInodes[0]); uint32_t s = lpnode->validSlots() - 1; - LeafNodeType *l = _allocator.mapLeafRef(lpnode->getChild(s)); + LeafNodeType *l = _allocator.mapLeafRef(lpnode->get_child_relaxed(s)); lpnode->writeKey(s, l->getLastKey()); } } @@ -256,11 +256,11 @@ normalize() if (pnode->validSlots() > 0) { uint32_t s = pnode->validSlots() - 1; InternalNodeType *n = - _allocator.mapInternalRef(pnode->getChild(s)); + _allocator.mapInternalRef(pnode->get_child_relaxed(s)); pnode->writeKey(s, n->getLastKey()); if (s > 0) { --s; - n = _allocator.mapInternalRef(pnode->getChild(s)); + n = _allocator.mapInternalRef(pnode->get_child_relaxed(s)); pnode->writeKey(s, n->getLastKey()); } } @@ -270,7 +270,7 @@ normalize() _allocator.mapInternalRef(leftInodes[level + 1]); uint32_t s = lpnode->validSlots() - 1; InternalNodeType *n = - _allocator.mapInternalRef(lpnode->getChild(s)); + _allocator.mapInternalRef(lpnode->get_child_relaxed(s)); lpnode->writeKey(s, n->getLastKey()); } } @@ -333,7 +333,7 @@ allocNewLeafNode() } inode = _inodes[level].data; assert(inode->validSlots() > 0); - NodeRef lcRef(inode->getLastChild()); + NodeRef lcRef(inode->get_last_child_relaxed()); inode->incValidLeaves(_allocator.validLeaves(lcRef)); inode->update(inode->validSlots() - 1, level == 0 ? @@ -358,7 +358,7 @@ allocNewLeafNode() } while (level > 0) { assert(inode->validSlots() > 0); - child = inode->getLastChild(); + child = inode->get_last_child_relaxed(); assert(!_allocator.isLeafRef(child)); inode = _allocator.mapInternalRef(child); level--; diff --git a/vespalib/src/vespa/vespalib/btree/btreeinserter.hpp b/vespalib/src/vespa/vespalib/btree/btreeinserter.hpp index b5980e53f93..de6454f8bae 100644 --- a/vespalib/src/vespa/vespalib/btree/btreeinserter.hpp +++ b/vespalib/src/vespa/vespalib/btree/btreeinserter.hpp @@ -34,17 +34,17 @@ BTreeInserter<KeyT, DataT, AggrT, CompareT, TraitsT, AggrCalcT>::rebalanceLeafEn auto &pathElem = itr.getPath(0); InternalNodeType *parentNode = pathElem.getWNode(); uint32_t parentIdx = pathElem.getIdx(); - BTreeNode::Ref leafRef = parentNode->getChild(parentIdx); + BTreeNode::Ref leafRef = parentNode->get_child_relaxed(parentIdx); BTreeNode::Ref leftRef = BTreeNode::Ref(); LeafNodeType *leftNode = nullptr; BTreeNode::Ref rightRef = BTreeNode::Ref(); LeafNodeType *rightNode = nullptr; if (parentIdx > 0) { - leftRef = parentNode->getChild(parentIdx - 1); + leftRef = parentNode->get_child_relaxed(parentIdx - 1); leftNode = allocator.mapLeafRef(leftRef); } if (parentIdx + 1 < parentNode->validSlots()) { - rightRef = parentNode->getChild(parentIdx + 1); + rightRef = parentNode->get_child_relaxed(parentIdx + 1); rightNode = allocator.mapLeafRef(rightRef); } if (leftNode != nullptr && leftNode->validSlots() < LeafNodeType::maxSlots() && @@ -138,7 +138,7 @@ insert(BTreeNode::Ref &root, idx = pe.getIdx(); AggrT olda(AggrCalcT::hasAggregated() ? node->getAggregated() : AggrT()); - BTreeNode::Ref subNode = node->getChild(idx); + BTreeNode::Ref subNode = node->get_child_relaxed(idx); node->update(idx, *lastKey, subNode); node->incValidLeaves(1); if (NodeAllocatorType::isValidRef(splitNodeRef)) { diff --git a/vespalib/src/vespa/vespalib/btree/btreeiterator.hpp b/vespalib/src/vespa/vespalib/btree/btreeiterator.hpp index 042779f1b1b..8ecd26835c4 100644 --- a/vespalib/src/vespa/vespalib/btree/btreeiterator.hpp +++ b/vespalib/src/vespa/vespalib/btree/btreeiterator.hpp @@ -1163,13 +1163,13 @@ thaw(BTreeNode::Ref rootRef) rootRef; assert(node == allocator.mapInternalRef(nodeRef)); if (!node->getFrozen()) { - node->setChild(pe.getIdx(), childRef); + node->set_child_relaxed(pe.getIdx(), childRef); return rootRef; } InternalNodeTypeRefPair thawed = allocator.thawNode(nodeRef, node); node = thawed.data; pe.setNode(node); - node->setChild(pe.getIdx(), childRef); + node->set_child_relaxed(pe.getIdx(), childRef); childRef = thawed.ref; ++level; } diff --git a/vespalib/src/vespa/vespalib/btree/btreenode.h b/vespalib/src/vespa/vespalib/btree/btreenode.h index 468f17fcd1a..deeaad40ae6 100644 --- a/vespalib/src/vespa/vespalib/btree/btreenode.h +++ b/vespalib/src/vespa/vespalib/btree/btreenode.h @@ -336,8 +336,10 @@ private: public: BTreeNode::Ref getChild(uint32_t idx) const { return getData(idx); } + BTreeNode::Ref get_child_relaxed(uint32_t idx) const { return getData(idx); } void setChild(uint32_t idx, BTreeNode::Ref child) { setData(idx, child); } - BTreeNode::Ref getLastChild() const { return getChild(validSlots() - 1); } + void set_child_relaxed(uint32_t idx, BTreeNode::Ref child) { setData(idx, child); } + BTreeNode::Ref get_last_child_relaxed() const { return get_child_relaxed(validSlots() - 1); } uint32_t validLeaves() const { return _validLeaves; } void setValidLeaves(uint32_t newValidLeaves) { _validLeaves = newValidLeaves; } void incValidLeaves(uint32_t delta) { _validLeaves += delta; } diff --git a/vespalib/src/vespa/vespalib/btree/btreenode.hpp b/vespalib/src/vespa/vespalib/btree/btreenode.hpp index 547dd6f5f3f..62773e57c6f 100644 --- a/vespalib/src/vespa/vespalib/btree/btreenode.hpp +++ b/vespalib/src/vespa/vespalib/btree/btreenode.hpp @@ -273,7 +273,7 @@ splitInsert(BTreeInternalNode *splitNode, uint32_t idx, const KeyT &key, for (uint32_t i = sih.getMedian(); i < validSlots(); ++i) { splitNode->_keys[i - sih.getMedian()] = _keys[i]; splitNode->setData(i - sih.getMedian(), getData(i)); - splitLeaves += allocator.validLeaves(getData(i)); + splitLeaves += allocator.validLeaves(getChild(i)); } splitNode->_validLeaves = splitLeaves; this->cleanRange(sih.getMedian(), validSlots()); @@ -316,7 +316,7 @@ BTreeInternalNode<KeyT, AggrT, NumSlots>::countValidLeaves(uint32_t start, uint3 assert(end <= validSlots()); uint32_t leaves = 0; for (uint32_t i = start; i < end; ++i) { - leaves += allocator.validLeaves(getData(i)); + leaves += allocator.validLeaves(getChild(i)); } return leaves; } diff --git a/vespalib/src/vespa/vespalib/btree/btreeremover.hpp b/vespalib/src/vespa/vespalib/btree/btreeremover.hpp index e0e41c1dd2d..24155abcff9 100644 --- a/vespalib/src/vespa/vespalib/btree/btreeremover.hpp +++ b/vespalib/src/vespa/vespalib/btree/btreeremover.hpp @@ -25,11 +25,11 @@ steal(InternalNodeType *pNode, BTreeNode::Ref rightVictimRef = BTreeNode::Ref(); NodeType * rightVictim = nullptr; if (idx > 0) { - leftVictimRef = pNode->getChild(idx - 1); + leftVictimRef = pNode->get_child_relaxed(idx - 1); leftVictim = allocator.template mapRef<NodeType>(leftVictimRef); } if (idx + 1 < pNode->validSlots()) { - rightVictimRef = pNode->getChild(idx + 1); + rightVictimRef = pNode->get_child_relaxed(idx + 1); rightVictim = allocator.template mapRef<NodeType>(rightVictimRef); } if (leftVictim != nullptr && @@ -141,7 +141,7 @@ remove(BTreeNode::Ref &root, idx = pe.getIdx(); AggrT olda(AggrCalcT::hasAggregated() ? node->getAggregated() : AggrT()); - BTreeNode::Ref subNode = node->getChild(idx); + BTreeNode::Ref subNode = node->get_child_relaxed(idx); node->update(idx, allocator.getLastKey(subNode), subNode); node->decValidLeaves(1); if (level == 0) { diff --git a/vespalib/src/vespa/vespalib/datastore/buffer_type.cpp b/vespalib/src/vespa/vespalib/datastore/buffer_type.cpp index 372370bc2d5..ca908d48210 100644 --- a/vespalib/src/vespa/vespalib/datastore/buffer_type.cpp +++ b/vespalib/src/vespa/vespalib/datastore/buffer_type.cpp @@ -2,6 +2,7 @@ #include "atomic_entry_ref.h" #include "buffer_type.hpp" +#include <algorithm> #include <cassert> #include <cmath> diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp index 83e9b10c6d6..ec3b0c54bda 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp @@ -56,7 +56,7 @@ void UniqueStoreEnumerator<RefT>::enumerateValues() { _next_enum_val = 1; - _dict_snapshot->foreach_key([this](EntryRef ref) { enumerateValue(ref); }); + _dict_snapshot->foreach_key([this](EntryRef ref) noexcept { enumerateValue(ref); }); } template <typename RefT> diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp b/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp index 3b063ce6805..76072aa6906 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp @@ -24,15 +24,17 @@ populationCount(const uint64_t *a, size_t sz) { return count; } -template<typename T> +template<typename T, unsigned ChunkSize> T get(const void * base, bool invert) { + static_assert(sizeof(T) == ChunkSize, "sizeof(T) == ChunkSize"); T v; memcpy(&v, base, sizeof(T)); return __builtin_expect(invert, false) ? ~v : v; } -template <typename T> +template <typename T, unsigned ChunkSize> const T * cast(const void * ptr, size_t offsetBytes) { + static_assert(sizeof(T) == ChunkSize, "sizeof(T) == ChunkSize"); return static_cast<const T *>(static_cast<const void *>(static_cast<const char *>(ptr) + offsetBytes)); } @@ -43,14 +45,14 @@ andChunks(size_t offset, const std::vector<std::pair<const void *, bool>> & src, static_assert(sizeof(Chunk) == ChunkSize, "sizeof(Chunk) == ChunkSize"); static_assert(ChunkSize*Chunks == 64, "ChunkSize*Chunks == 64"); Chunk * chunk = static_cast<Chunk *>(dest); - const Chunk * tmp = cast<Chunk>(src[0].first, offset); + const Chunk * tmp = cast<Chunk, ChunkSize>(src[0].first, offset); for (size_t n=0; n < Chunks; n++) { - chunk[n] = get<Chunk>(tmp+n, src[0].second); + chunk[n] = get<Chunk, ChunkSize>(tmp+n, src[0].second); } for (size_t i(1); i < src.size(); i++) { - tmp = cast<Chunk>(src[i].first, offset); + tmp = cast<Chunk, ChunkSize>(src[i].first, offset); for (size_t n=0; n < Chunks; n++) { - chunk[n] &= get<Chunk>(tmp+n, src[i].second); + chunk[n] &= get<Chunk, ChunkSize>(tmp+n, src[i].second); } } } @@ -62,14 +64,14 @@ orChunks(size_t offset, const std::vector<std::pair<const void *, bool>> & src, static_assert(sizeof(Chunk) == ChunkSize, "sizeof(Chunk) == ChunkSize"); static_assert(ChunkSize*Chunks == 64, "ChunkSize*Chunks == 64"); Chunk * chunk = static_cast<Chunk *>(dest); - const Chunk * tmp = cast<Chunk>(src[0].first, offset); + const Chunk * tmp = cast<Chunk, ChunkSize>(src[0].first, offset); for (size_t n=0; n < Chunks; n++) { - chunk[n] = get<Chunk>(tmp+n, src[0].second); + chunk[n] = get<Chunk, ChunkSize>(tmp+n, src[0].second); } for (size_t i(1); i < src.size(); i++) { - tmp = cast<Chunk>(src[i].first, offset); + tmp = cast<Chunk, ChunkSize>(src[i].first, offset); for (size_t n=0; n < Chunks; n++) { - chunk[n] |= get<Chunk>(tmp+n, src[i].second); + chunk[n] |= get<Chunk, ChunkSize>(tmp+n, src[i].second); } } } diff --git a/vespalib/src/vespa/vespalib/net/async_resolver.cpp b/vespalib/src/vespa/vespalib/net/async_resolver.cpp index f66d34d4174..7eab9d7c13c 100644 --- a/vespalib/src/vespa/vespalib/net/async_resolver.cpp +++ b/vespalib/src/vespa/vespalib/net/async_resolver.cpp @@ -155,6 +155,8 @@ AsyncResolver::AsyncResolver(HostResolver::SP resolver, size_t num_threads) { } +AsyncResolver::~AsyncResolver() = default; + void AsyncResolver::wait_for_pending_resolves() { _executor->sync(); diff --git a/vespalib/src/vespa/vespalib/net/async_resolver.h b/vespalib/src/vespa/vespalib/net/async_resolver.h index 28d04e76c16..64e2285acd2 100644 --- a/vespalib/src/vespa/vespalib/net/async_resolver.h +++ b/vespalib/src/vespa/vespalib/net/async_resolver.h @@ -124,6 +124,7 @@ private: AsyncResolver(HostResolver::SP resolver, size_t num_threads); public: + ~AsyncResolver(); void resolve_async(const vespalib::string &spec, ResultHandler::WP result_handler); void wait_for_pending_resolves(); static AsyncResolver::SP create(Params params); diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp index 91dc64e4165..832d52c0383 100644 --- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp +++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.cpp @@ -5,6 +5,8 @@ namespace vespalib { +MaybeTlsCryptoEngine::~MaybeTlsCryptoEngine() = default; + CryptoSocket::UP MaybeTlsCryptoEngine::create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) { diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h index 8c8a4452c80..2b82d6eb8bc 100644 --- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h +++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_engine.h @@ -28,6 +28,7 @@ public: : _null_engine(std::make_shared<NullCryptoEngine>()), _tls_engine(std::move(tls_engine)), _use_tls_when_client(use_tls_when_client) {} + ~MaybeTlsCryptoEngine() override; bool use_tls_when_client() const override { return _use_tls_when_client; } bool always_use_tls_when_server() const override { return false; } CryptoSocket::UP create_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override; diff --git a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp index 119b4b93a54..9ae270780b5 100644 --- a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp +++ b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.cpp @@ -6,6 +6,8 @@ namespace vespalib { +TlsCryptoEngine::~TlsCryptoEngine() = default; + TlsCryptoEngine::TlsCryptoEngine(net::tls::TransportSecurityOptions tls_opts, net::tls::AuthorizationMode authz_mode) : _tls_ctx(net::tls::TlsContext::create_default_context(tls_opts, authz_mode)) { diff --git a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h index 13a514f6954..0e05363ab1b 100644 --- a/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h +++ b/vespalib/src/vespa/vespalib/net/tls/tls_crypto_engine.h @@ -25,6 +25,7 @@ private: public: explicit TlsCryptoEngine(net::tls::TransportSecurityOptions tls_opts, net::tls::AuthorizationMode authz_mode = net::tls::AuthorizationMode::Enforce); + ~TlsCryptoEngine() override; std::unique_ptr<TlsCryptoSocket> create_tls_client_crypto_socket(SocketHandle socket, const SocketSpec &spec) override; std::unique_ptr<TlsCryptoSocket> create_tls_server_crypto_socket(SocketHandle socket) override; bool use_tls_when_client() const override { return true; } diff --git a/vespalib/src/vespa/vespalib/test/btree/btree_printer.h b/vespalib/src/vespa/vespalib/test/btree/btree_printer.h index acac4df90c8..8430dc894ba 100644 --- a/vespalib/src/vespa/vespalib/test/btree/btree_printer.h +++ b/vespalib/src/vespa/vespalib/test/btree/btree_printer.h @@ -60,7 +60,7 @@ class BTreePrinter return; } for (uint32_t i = 0; i < n.validSlots(); ++i) { - printNode(n.getData(i)); + printNode(n.getChild(i)); } } diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt index 752bf60c688..747ed736aad 100644 --- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt +++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt @@ -18,6 +18,7 @@ vespa_add_library(vespalib_vespalib_util OBJECT classname.cpp compress.cpp compressor.cpp + count_down_latch.cpp cpu_usage.cpp destructor_callbacks.cpp dual_merge_director.cpp @@ -26,6 +27,7 @@ vespa_add_library(vespalib_vespalib_util OBJECT exceptions.cpp executor_idle_tracking.cpp file_area_freelist.cpp + gate.cpp gencnt.cpp generationhandler.cpp generationholder.cpp diff --git a/vespalib/src/vespa/vespalib/util/count_down_latch.cpp b/vespalib/src/vespa/vespalib/util/count_down_latch.cpp new file mode 100644 index 00000000000..5064a0a962f --- /dev/null +++ b/vespalib/src/vespa/vespalib/util/count_down_latch.cpp @@ -0,0 +1,9 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "count_down_latch.h" + +namespace vespalib { + +CountDownLatch::~CountDownLatch() = default; + +} diff --git a/vespalib/src/vespa/vespalib/util/count_down_latch.h b/vespalib/src/vespa/vespalib/util/count_down_latch.h index 613a60e90c5..d4298f0d5a9 100644 --- a/vespalib/src/vespa/vespalib/util/count_down_latch.h +++ b/vespalib/src/vespa/vespalib/util/count_down_latch.h @@ -90,7 +90,7 @@ public: /** * Empty. Needs to be virtual to reduce compiler warnings. **/ - virtual ~CountDownLatch() = default; + virtual ~CountDownLatch(); }; } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/util/gate.cpp b/vespalib/src/vespa/vespalib/util/gate.cpp new file mode 100644 index 00000000000..485c29dc5c8 --- /dev/null +++ b/vespalib/src/vespa/vespalib/util/gate.cpp @@ -0,0 +1,9 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "gate.h" + +namespace vespalib { + +Gate::~Gate() = default; + +} diff --git a/vespalib/src/vespa/vespalib/util/gate.h b/vespalib/src/vespa/vespalib/util/gate.h index c914a4f0911..315adb2939e 100644 --- a/vespalib/src/vespa/vespalib/util/gate.h +++ b/vespalib/src/vespa/vespalib/util/gate.h @@ -17,6 +17,7 @@ public: * Sets the initial count to 1. **/ Gate() noexcept : CountDownLatch(1) {} + ~Gate() override; }; } // namespace vespalib diff --git a/vespamalloc/src/tests/allocfree/allocfree.cpp b/vespamalloc/src/tests/allocfree/allocfree.cpp index 2b603fdd033..32f881a4b96 100644 --- a/vespamalloc/src/tests/allocfree/allocfree.cpp +++ b/vespamalloc/src/tests/allocfree/allocfree.cpp @@ -19,27 +19,34 @@ class FreeWorker : public Consumer { public: FreeWorker(uint32_t maxQueue, bool inverse) : Consumer (maxQueue, inverse) {} + ~FreeWorker() override; private: void consume(void * p) override { free(p); } }; +FreeWorker::~FreeWorker() = default; + //----------------------------------------------------------------------------- class MallocWorker : public Producer { public: MallocWorker(uint32_t size, uint32_t cnt, FreeWorker &target) : Producer(cnt, target), _size(size) {} + ~MallocWorker() override; private: uint32_t _size; void * produce() override { return malloc(_size); } }; +MallocWorker::~MallocWorker() = default; + //----------------------------------------------------------------------------- class MallocFreeWorker : public ProducerConsumer { public: MallocFreeWorker(uint32_t size, uint32_t cnt, bool inverse) : ProducerConsumer(cnt, inverse), _size(size) { } + ~MallocFreeWorker() override; private: uint32_t _size; @@ -47,6 +54,8 @@ private: void consume(void * p) override { free(p); } }; +MallocFreeWorker::~MallocFreeWorker() = default; + //----------------------------------------------------------------------------- int Test::Main() { diff --git a/vespamalloc/src/tests/doubledelete/doubledelete.cpp b/vespamalloc/src/tests/doubledelete/doubledelete.cpp index bd04be2da5d..fd3eadddd69 100644 --- a/vespamalloc/src/tests/doubledelete/doubledelete.cpp +++ b/vespamalloc/src/tests/doubledelete/doubledelete.cpp @@ -3,12 +3,19 @@ void *savedptr; +void delete_ptr_real(char *ptr) +{ + delete ptr; +} + +void (*delete_ptr)(char *ptr) = delete_ptr_real; + int main(int argc, char *argv[]) { (void) argc; (void) argv; char * a = new char; savedptr = a; - delete a; - delete a; + delete_ptr(a); + delete_ptr(a); } diff --git a/vespamalloc/src/tests/overwrite/overwrite.cpp b/vespamalloc/src/tests/overwrite/overwrite.cpp index 151207e95fa..aae5cccb696 100644 --- a/vespamalloc/src/tests/overwrite/overwrite.cpp +++ b/vespamalloc/src/tests/overwrite/overwrite.cpp @@ -17,6 +17,13 @@ void overwrite_memory_real(char *ptr, int offset) void (*overwrite_memory)(char *ptr, int offset) = overwrite_memory_real; +void delete_vec_real(char *ptr) +{ + delete [] ptr; +} + +void (*delete_vec)(char *ptr) = delete_vec_real; + class Test : public TestApp { public: @@ -43,7 +50,7 @@ void Test::testFillValue(char *a) char *d = new char[256]; memset(d, 0x77, 256); check_ptr(d); - delete [] d; + delete_vec(d); EXPECT_EQUAL((int)d[0], 0x66); EXPECT_EQUAL((int)d[1], 0x66); EXPECT_EQUAL((int)d[255], 0x66); @@ -84,7 +91,7 @@ void Test::verifyWriteAfterFreeDetection() // Make sure that enough blocks of memory is allocated and freed. char * a = new char[256]; check_ptr(a); - delete [] a; + delete_vec(a); for (size_t i(0); i < 100; i++) { char *d = new char[256]; check_ptr(d); |