diff options
93 files changed, 938 insertions, 1137 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java index 24998a49faf..e6dd40faaca 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceConfirmation.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.Optional; /** * InstanceConfirmation object as per Athenz InstanceConfirmation API. @@ -29,8 +28,6 @@ import java.util.Optional; */ public class InstanceConfirmation { - static final String HOSTNAME_ATTRIBUTE = "hostname"; - @JsonProperty("provider") public final String provider; @JsonProperty("domain") public final String domain; @JsonProperty("service") public final String service; @@ -56,10 +53,6 @@ public class InstanceConfirmation { attributes.put(name, value); } - public Optional<String> getInstanceHostname() { - return Optional.ofNullable(attributes.get(HOSTNAME_ATTRIBUTE)); - } - @Override public String toString() { return "InstanceConfirmation{" + diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java index 54611172b57..f1a93e58526 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidator.java @@ -10,7 +10,6 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.log.LogLevel; import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; -import com.yahoo.vespa.athenz.identityprovider.api.IdentityType; import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; import com.yahoo.vespa.athenz.identityprovider.client.IdentityDocumentSigner; @@ -159,34 +158,6 @@ public class InstanceValidator { log.log(LogLevel.WARNING, "Invalid InstanceConfirmation, wrong ip in : " + vespaUniqueInstanceId); return false; } - - // Validate hostname - boolean hasValidHostname = - confirmation.getInstanceHostname() - .map(requestHostname -> validateHostname(vespaUniqueInstanceId, node, requestHostname)) - .orElse(true); - if (!hasValidHostname) { - return false; - } - - return true; - } - - private static boolean validateHostname(VespaUniqueInstanceId vespaUniqueInstanceId, Node node, String requestedHostname) { - String nodeHostname = node.hostname(); - if (vespaUniqueInstanceId.type() == IdentityType.TENANT) { - log.log(LogLevel.WARNING, "Instance hostname not allowed in tenant certificates"); - return false; - } - if (!nodeHostname.equals(requestedHostname)) { - log.log(LogLevel.WARNING, - String.format( - "Invalid instance confirmation: request instance hostname is '%s', but node repository has '%s'", - requestedHostname, - nodeHostname)); - - return false; - } return true; } diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java index 957b71a64bf..d5787516254 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java @@ -1,6 +1,7 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.athenz.instanceproviderservice.instanceconfirmation; +import com.google.common.collect.ImmutableList; import com.yahoo.component.Version; import com.yahoo.config.model.api.ApplicationInfo; import com.yahoo.config.model.api.HostInfo; @@ -122,7 +123,7 @@ public class InstanceValidatorTest { nodeList = allocateNode(nodeList, node, applicationId); when(nodeRepository.getNodes()).thenReturn(nodeList); String nodeIp = node.ipAddresses().stream().findAny().orElseThrow(() -> new RuntimeException("No ipaddress for mocked node")); - InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, IdentityType.NODE, node.hostname(), List.of(nodeIp)); + InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, ImmutableList.of(nodeIp)); assertTrue(instanceValidator.isValidRefresh(instanceConfirmation)); } @@ -139,41 +140,7 @@ public class InstanceValidatorTest { String nodeIp = node.ipAddresses().stream().findAny().orElseThrow(() -> new RuntimeException("No ipaddress for mocked node")); // Add invalid ip to list of ip addresses - InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, IdentityType.NODE, node.hostname(), List.of(nodeIp, "::ff")); - - assertFalse(instanceValidator.isValidRefresh(instanceConfirmation)); - } - - @Test - public void rejects_invalid_hostname() { - NodeRepository nodeRepository = mock(NodeRepository.class); - InstanceValidator instanceValidator = new InstanceValidator(null, null, nodeRepository); - - List<Node> nodeList = createNodes(10); - Node node = nodeList.get(0); - nodeList = allocateNode(nodeList, node, applicationId); - when(nodeRepository.getNodes()).thenReturn(nodeList); - String nodeIp = node.ipAddresses().stream().findAny().orElseThrow(() -> new RuntimeException("No ipaddress for mocked node")); - - // Add invalid hostname to request - InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, IdentityType.NODE, "invalidhostname", List.of(nodeIp)); - - assertFalse(instanceValidator.isValidRefresh(instanceConfirmation)); - } - - @Test - public void rejects_hostname_for_tenant_certificates() { - NodeRepository nodeRepository = mock(NodeRepository.class); - InstanceValidator instanceValidator = new InstanceValidator(null, null, nodeRepository); - - List<Node> nodeList = createNodes(10); - Node node = nodeList.get(0); - nodeList = allocateNode(nodeList, node, applicationId); - when(nodeRepository.getNodes()).thenReturn(nodeList); - String nodeIp = node.ipAddresses().stream().findAny().orElseThrow(() -> new RuntimeException("No ipaddress for mocked node")); - - // Request tenant certificate with valid hostname - InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, IdentityType.TENANT, node.hostname(), List.of(nodeIp)); + InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, ImmutableList.of(nodeIp, "::ff")); assertFalse(instanceValidator.isValidRefresh(instanceConfirmation)); } @@ -185,7 +152,7 @@ public class InstanceValidatorTest { List<Node> nodeList = createNodes(10); when(nodeRepository.getNodes()).thenReturn(nodeList); - InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, IdentityType.NODE, nodeList.get(0).hostname(), List.of("::11")); + InstanceConfirmation instanceConfirmation = createRefreshInstanceConfirmation(applicationId, domain, service, ImmutableList.of("::11")); assertFalse(instanceValidator.isValidRefresh(instanceConfirmation)); @@ -206,11 +173,10 @@ public class InstanceValidatorTest { return createInstanceConfirmation(vespaUniqueInstanceId, domain, service, signedIdentityDocument); } - private InstanceConfirmation createRefreshInstanceConfirmation(ApplicationId applicationId, String domain, String service, IdentityType identityType, String hostname, List<String> ips) { - VespaUniqueInstanceId vespaUniqueInstanceId = new VespaUniqueInstanceId(0, "default", applicationId.instance().value(), applicationId.application().value(), applicationId.tenant().value(), "us-north-1", "dev", identityType); + private InstanceConfirmation createRefreshInstanceConfirmation(ApplicationId applicationId, String domain, String service, List<String> ips) { + VespaUniqueInstanceId vespaUniqueInstanceId = new VespaUniqueInstanceId(0, "default", applicationId.instance().value(), applicationId.application().value(), applicationId.tenant().value(), "us-north-1", "dev", IdentityType.NODE); InstanceConfirmation instanceConfirmation = createInstanceConfirmation(vespaUniqueInstanceId, domain, service, null); instanceConfirmation.set("sanIP", String.join(",", ips)); - instanceConfirmation.set(InstanceConfirmation.HOSTNAME_ATTRIBUTE, hostname); return instanceConfirmation; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java index d618464fc2a..e6639a33738 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java @@ -31,6 +31,11 @@ public class Node { private final long wantedRestartGeneration; private final long rebootGeneration; private final long wantedRebootGeneration; + private final double vcpu; + private final double memoryGb; + private final double diskGb; + private final double bandwidthGbps; + private final boolean fastDisk; private final String canonicalFlavor; private final String clusterId; private final ClusterType clusterType; @@ -38,7 +43,7 @@ public class Node { public Node(HostName hostname, State state, NodeType type, Optional<ApplicationId> owner, Version currentVersion, Version wantedVersion, Version currentOsVersion, Version wantedOsVersion, ServiceState serviceState, long restartGeneration, long wantedRestartGeneration, long rebootGeneration, long wantedRebootGeneration, - String canonicalFlavor, String clusterId, ClusterType clusterType) { + double vcpu, double memoryGb, double diskGb, double bandwidthGbps, boolean fastDisk, String canonicalFlavor, String clusterId, ClusterType clusterType) { this.hostname = hostname; this.state = state; this.type = type; @@ -52,6 +57,11 @@ public class Node { this.wantedRestartGeneration = wantedRestartGeneration; this.rebootGeneration = rebootGeneration; this.wantedRebootGeneration = wantedRebootGeneration; + this.vcpu = vcpu; + this.memoryGb = memoryGb; + this.diskGb = diskGb; + this.bandwidthGbps = bandwidthGbps; + this.fastDisk = fastDisk; this.canonicalFlavor = canonicalFlavor; this.clusterId = clusterId; this.clusterType = clusterType; @@ -62,7 +72,7 @@ public class Node { Version currentVersion, Version wantedVersion) { this(hostname, state, type, owner, currentVersion, wantedVersion, Version.emptyVersion, Version.emptyVersion, ServiceState.unorchestrated, 0, 0, 0, 0, - "d-2-8-50", "cluster", ClusterType.container); + 2, 8, 50, 1, true, "d-2-8-50", "cluster", ClusterType.container); } public HostName hostname() { @@ -115,6 +125,26 @@ public class Node { return wantedRebootGeneration; } + public double vcpu() { + return vcpu; + } + + public double memoryGb() { + return memoryGb; + } + + public double diskGb() { + return diskGb; + } + + public double bandwidthGbps() { + return bandwidthGbps; + } + + public boolean fastDisk() { + return fastDisk; + } + public String canonicalFlavor() { return canonicalFlavor; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java index 916a388692e..fd6b5b48d10 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java @@ -49,6 +49,11 @@ public interface NodeRepository { n.getRestartGeneration(), n.getCurrentRebootGeneration(), n.getRebootGeneration(), + n.getMinCpuCores(), + n.getMinMainMemoryAvailableGb(), + n.getMinDiskAvailableGb(), + n.getBandwidth() / 1000, + n.getFastDisk(), n.getCanonicalFlavor(), n.getMembership().clusterid, clusterTypeOf(n.getMembership().clustertype))) diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZtsClientMock.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZtsClientMock.java index 752c003cf75..a2217246c1d 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZtsClientMock.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/mock/ZtsClientMock.java @@ -44,12 +44,12 @@ public class ZtsClientMock implements ZtsClient { } @Override - public InstanceIdentity registerInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String hostname, String attestationData, Pkcs10Csr csr) { + public InstanceIdentity registerInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String attestationData, Pkcs10Csr csr) { throw new UnsupportedOperationException(); } @Override - public InstanceIdentity refreshInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String instanceId, String hostname, Pkcs10Csr csr) { + public InstanceIdentity refreshInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String instanceId, Pkcs10Csr csr) { throw new UnsupportedOperationException(); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 3392576643f..a04f9a99ec0 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -391,6 +391,11 @@ public class ApplicationApiHandler extends LoggingRequestHandler { nodeObject.setString("orchestration", valueOf(node.serviceState())); nodeObject.setString("version", node.currentVersion().toString()); nodeObject.setString("flavor", node.canonicalFlavor()); + nodeObject.setDouble("vcpu", node.vcpu()); + nodeObject.setDouble("memoryGb", node.memoryGb()); + nodeObject.setDouble("diskGb", node.diskGb()); + nodeObject.setDouble("bandwidthGbps", node.bandwidthGbps()); + nodeObject.setBool("fastDisk", node.fastDisk()); nodeObject.setString("clusterId", node.clusterId()); nodeObject.setString("clusterType", valueOf(node.clusterType())); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java index 45c2df5cb77..61cb5c4a2ed 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/NodeRepositoryMock.java @@ -124,6 +124,11 @@ public class NodeRepositoryMock implements NodeRepository { node.wantedRestartGeneration(), node.rebootGeneration(), node.wantedRebootGeneration(), + node.vcpu(), + node.memoryGb(), + node.diskGb(), + node.bandwidthGbps(), + node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())) @@ -169,6 +174,11 @@ public class NodeRepositoryMock implements NodeRepository { node.wantedRestartGeneration() + 1, node.rebootGeneration(), node.wantedRebootGeneration(), + node.vcpu(), + node.memoryGb(), + node.diskGb(), + node.bandwidthGbps(), + node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); @@ -188,6 +198,11 @@ public class NodeRepositoryMock implements NodeRepository { node.wantedRestartGeneration(), node.rebootGeneration(), node.wantedRebootGeneration(), + node.vcpu(), + node.memoryGb(), + node.diskGb(), + node.bandwidthGbps(), + node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); @@ -207,6 +222,11 @@ public class NodeRepositoryMock implements NodeRepository { node.wantedRestartGeneration(), node.rebootGeneration(), node.wantedRebootGeneration() + 1, + node.vcpu(), + node.memoryGb(), + node.diskGb(), + node.bandwidthGbps(), + node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); @@ -226,6 +246,11 @@ public class NodeRepositoryMock implements NodeRepository { node.wantedRestartGeneration(), node.rebootGeneration() + 1, node.wantedRebootGeneration(), + node.vcpu(), + node.memoryGb(), + node.diskGb(), + node.bandwidthGbps(), + node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java index 38aa4af4756..4bee9fe2f75 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgraderTest.java @@ -4,10 +4,10 @@ package com.yahoo.vespa.hosted.controller.maintenance; import com.yahoo.component.Version; import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.SystemName; -import com.yahoo.config.provision.zone.ZoneApi; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; import com.yahoo.config.provision.zone.UpgradePolicy; +import com.yahoo.config.provision.zone.ZoneApi; import com.yahoo.config.provision.zone.ZoneId; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; import com.yahoo.vespa.hosted.controller.application.SystemApplication; import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester; import com.yahoo.vespa.hosted.controller.integration.NodeRepositoryMock; @@ -164,7 +164,8 @@ public class OsUpgraderTest { node.hostname(), node.state(), node.type(), node.owner(), node.currentVersion(), node.wantedVersion(), node.wantedOsVersion(), node.wantedOsVersion(), node.serviceState(), node.restartGeneration(), node.wantedRestartGeneration(), node.rebootGeneration(), - node.wantedRebootGeneration(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); + node.wantedRebootGeneration(), node.vcpu(), node.memoryGb(), node.diskGb(), + node.bandwidthGbps(), node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); } assertCurrent(version, application, zone); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-nodes.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-nodes.json index e673a610f87..a83c13719d9 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-nodes.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-nodes.json @@ -6,6 +6,11 @@ "orchestration": "unorchestrated", "version": "6.1", "flavor": "d-2-8-50", + "vcpu": 2.0, + "memoryGb": 8.0, + "diskGb": 50.0, + "bandwidthGbps": 1.0, + "fastDisk": true, "clusterId": "cluster", "clusterType": "container" } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java index 745a7af203b..653ab38dc3a 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiTest.java @@ -149,7 +149,8 @@ public class OsApiTest extends ControllerContainerTest { node.hostname(), node.state(), node.type(), node.owner(), node.currentVersion(), node.wantedVersion(), node.wantedOsVersion(), node.wantedOsVersion(), node.serviceState(), node.restartGeneration(), node.wantedRestartGeneration(), node.rebootGeneration(), - node.wantedRebootGeneration(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); + node.wantedRebootGeneration(), node.vcpu(), node.memoryGb(), node.diskGb(), + node.bandwidthGbps(), node.fastDisk(), node.canonicalFlavor(), node.clusterId(), node.clusterType())); } } } diff --git a/documentgen-test/etc/complex/music.sd b/documentgen-test/etc/complex/music.sd index b95edd2b4f3..1eb3939f4eb 100644 --- a/documentgen-test/etc/complex/music.sd +++ b/documentgen-test/etc/complex/music.sd @@ -21,6 +21,9 @@ search music { field year type int { indexing: attribute|index|summary } + field eitheror type bool { + indexing: attribute|summary + } annotation recordlabel {} annotation person { diff --git a/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java b/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java index 6b524af63ff..59b8d3b1e70 100644 --- a/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java +++ b/documentgen-test/src/test/java/com/yahoo/vespa/config/DocumentGenPluginTest.java @@ -99,17 +99,20 @@ public class DocumentGenPluginTest { @Test public void testRealBasic() { Music music = getMusicBasic(); - assertEquals(music.getFieldCount(), 6); - assertEquals(music.getArtist(), "Astroburger"); - assertEquals(music.getWeight_src(), 10.654f, 0); - assertEquals(music.getYear(), (Integer)2005); - assertEquals(music.getUri(), "http://astro.burger"); + assertEquals(7, music.getFieldCount()); + assertEquals("Astroburger", music.getArtist()); + assertEquals(10.654f, music.getWeight_src(), 0); + assertEquals((Integer)2005, music.getYear()); + assertEquals("http://astro.burger", music.getUri()); + assertFalse(music.getEitheror()); music.setUri(null); - assertEquals(music.getUri(), null); + assertNull(music.getUri()); music.setUri("https://astro.burger"); - assertEquals(music.getUri(), "https://astro.burger"); + assertEquals("https://astro.burger", music.getUri()); music.setYear(2006); - assertEquals(music.getYear(), (Integer)2006); + assertEquals((Integer)2006, music.getYear()); + music.setEitheror(true); + assertTrue(music.getEitheror()); } @Test @@ -772,6 +775,7 @@ public class DocumentGenPluginTest { music.setYear(2005); music.setUri("http://astro.burger"); music.setWeight_src(10.654f); + music.setEitheror(false); return music; } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java index f994530bef4..b952ae096b0 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java @@ -155,19 +155,13 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { private void registerIdentity(NodeAgentContext context, Path privateKeyFile, Path certificateFile, Path identityDocumentFile) { KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA); SignedIdentityDocument signedIdentityDocument = identityDocumentClient.getNodeIdentityDocument(context.hostname().value()); - Pkcs10Csr csr = - csrGenerator.generateInstanceCsr( - context.identity(), - signedIdentityDocument.providerUniqueId(), - signedIdentityDocument.instanceHostname(), - signedIdentityDocument.ipAddresses(), - keyPair); + Pkcs10Csr csr = csrGenerator.generateInstanceCsr( + context.identity(), signedIdentityDocument.providerUniqueId(), signedIdentityDocument.ipAddresses(), keyPair); try (ZtsClient ztsClient = new DefaultZtsClient(ztsEndpoint, hostIdentityProvider)) { InstanceIdentity instanceIdentity = ztsClient.registerInstance( configserverIdentity, context.identity(), - signedIdentityDocument.instanceHostname(), EntityBindingsMapper.toAttestationData(signedIdentityDocument), csr); EntityBindingsMapper.writeSignedIdentityDocumentToFile(identityDocumentFile, signedIdentityDocument); @@ -180,13 +174,8 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { private void refreshIdentity(NodeAgentContext context, Path privateKeyFile, Path certificateFile, Path identityDocumentFile) { SignedIdentityDocument identityDocument = EntityBindingsMapper.readSignedIdentityDocumentFromFile(identityDocumentFile); KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA); - Pkcs10Csr csr = csrGenerator - .generateInstanceCsr( - context.identity(), - identityDocument.providerUniqueId(), - identityDocument.instanceHostname(), - identityDocument.ipAddresses(), - keyPair); + Pkcs10Csr csr = csrGenerator.generateInstanceCsr( + context.identity(), identityDocument.providerUniqueId(), identityDocument.ipAddresses(), keyPair); SSLContext containerIdentitySslContext = new SslContextBuilder() .withKeyStore(privateKeyFile, certificateFile) @@ -199,7 +188,6 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { configserverIdentity, context.identity(), identityDocument.providerUniqueId().asDottedString(), - identityDocument.instanceHostname(), csr); writePrivateKeyAndCertificate(context.vespaUserOnHost(), privateKeyFile, keyPair.getPrivate(), certificateFile, instanceIdentity.certificate()); diff --git a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp index 36b1d64a7a9..edb97e12cdc 100644 --- a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp +++ b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp @@ -1,6 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <vespa/vespalib/testkit/testapp.h> #include <vespa/fastos/file.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> #include <vespa/searchcore/proton/attribute/attributedisklayout.h> @@ -13,7 +12,9 @@ #include <vespa/searchlib/common/indexmetainfo.h> #include <vespa/searchlib/index/dummyfileheadercontext.h> #include <vespa/searchlib/test/directory_handler.h> +#include <vespa/vespalib/datastore/datastorebase.h> #include <vespa/vespalib/io/fileutil.h> +#include <vespa/vespalib/testkit/testapp.h> #include <vespa/vespalib/util/threadstackexecutor.h> #include <vespa/log/log.h> diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_vector_explorer.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_vector_explorer.cpp index a070e907fbb..a1d5f72bc9d 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_vector_explorer.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_vector_explorer.cpp @@ -1,7 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "attribute_vector_explorer.h" -#include <vespa/searchlib/attribute/enumstorebase.h> +#include <vespa/searchlib/attribute/i_enum_store.h> #include <vespa/searchlib/attribute/multi_value_mapping.h> #include <vespa/searchlib/attribute/attributevector.h> #include <vespa/searchlib/attribute/ipostinglistattributebase.h> @@ -10,7 +10,7 @@ using search::attribute::Status; using search::AddressSpaceUsage; using search::AttributeVector; -using search::EnumStoreBase; +using search::IEnumStore; using vespalib::AddressSpace; using vespalib::MemoryUsage; using search::attribute::MultiValueMappingBase; @@ -74,7 +74,7 @@ convertMemoryUsageToSlime(const MemoryUsage &usage, Cursor &object) } void -convertEnumStoreToSlime(const EnumStoreBase &enumStore, Cursor &object) +convertEnumStoreToSlime(const IEnumStore &enumStore, Cursor &object) { object.setLong("numUniques", enumStore.getNumUniques()); convertMemoryUsageToSlime(enumStore.getMemoryUsage(), object.setObject("memoryUsage")); @@ -119,7 +119,7 @@ AttributeVectorExplorer::get_state(const vespalib::slime::Inserter &inserter, bo convertStatusToSlime(status, object.setObject("status")); convertGenerationToSlime(attr, object.setObject("generation")); convertAddressSpaceUsageToSlime(attr.getAddressSpaceUsage(), object.setObject("addressSpaceUsage")); - const EnumStoreBase *enumStore = attr.getEnumStoreBase(); + const IEnumStore *enumStore = attr.getEnumStoreBase(); if (enumStore) { convertEnumStoreToSlime(*enumStore, object.setObject("enumStore")); } diff --git a/searchlib/src/tests/attribute/attribute_test.cpp b/searchlib/src/tests/attribute/attribute_test.cpp index 833cddb91a7..bd1cfd45280 100644 --- a/searchlib/src/tests/attribute/attribute_test.cpp +++ b/searchlib/src/tests/attribute/attribute_test.cpp @@ -1638,9 +1638,9 @@ AttributeTest::testStatus() fillString(values, 16); uint32_t numDocs = 100; // No posting list - static constexpr size_t LeafNodeSize = 4 + sizeof(EnumStoreBase::Index) * EnumTreeTraits::LEAF_SLOTS; + static constexpr size_t LeafNodeSize = 4 + sizeof(IEnumStore::Index) * EnumTreeTraits::LEAF_SLOTS; static constexpr size_t InternalNodeSize = - 8 + (sizeof(EnumStoreBase::Index) + sizeof(datastore::EntryRef)) * EnumTreeTraits::INTERNAL_SLOTS; + 8 + (sizeof(IEnumStore::Index) + sizeof(datastore::EntryRef)) * EnumTreeTraits::INTERNAL_SLOTS; static constexpr size_t NestedVectorSize = 24; // sizeof(vespalib::Array) { @@ -1683,7 +1683,7 @@ AttributeTest::testStatus() expUsed += numUniq * 32; // enum store (16 unique values, 32 bytes per entry) // multi value mapping (numdocs * sizeof(MappingIndex) + numvalues * sizeof(EnumIndex) + // numdocs * sizeof(Array<EnumIndex>) (due to vector vector)) - expUsed += numDocs * sizeof(datastore::EntryRef) + numDocs * numValuesPerDoc * sizeof(EnumStoreBase::Index) + ((numValuesPerDoc > 1024) ? numDocs * NestedVectorSize : 0); + expUsed += numDocs * sizeof(datastore::EntryRef) + numDocs * numValuesPerDoc * sizeof(IEnumStore::Index) + ((numValuesPerDoc > 1024) ? numDocs * NestedVectorSize : 0); EXPECT_GREATER_EQUAL(ptr->getStatus().getUsed(), expUsed); EXPECT_GREATER_EQUAL(ptr->getStatus().getAllocated(), expUsed); } diff --git a/searchlib/src/tests/attribute/comparator/comparator_test.cpp b/searchlib/src/tests/attribute/comparator/comparator_test.cpp index 6ad2a7ebe3b..a2000c48423 100644 --- a/searchlib/src/tests/attribute/comparator/comparator_test.cpp +++ b/searchlib/src/tests/attribute/comparator/comparator_test.cpp @@ -24,7 +24,7 @@ typedef EnumStoreT<StringEntryType> StringEnumStore; typedef EnumStoreComparatorT<StringEntryType> StringComparator; typedef EnumStoreFoldedComparatorT<StringEntryType> FoldedStringComparator; -typedef EnumStoreBase::Index EnumIndex; +typedef IEnumStore::Index EnumIndex; typedef BTreeRoot<EnumIndex, BTreeNoLeafData, btree::NoAggregated, diff --git a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp index 29c35f11e65..c4ba8eecf43 100644 --- a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp +++ b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp @@ -15,7 +15,7 @@ size_t enumStoreAlign(size_t size) return (size + 15) & -UINT64_C(16); } -// EnumStoreBase::Index(0,0) is reserved thus 16 bytes are reserved in buffer 0 +// IEnumStore::Index(0,0) is reserved thus 16 bytes are reserved in buffer 0 const uint32_t RESERVED_BYTES = 16u; typedef EnumStoreT<NumericEntryType<uint32_t> > NumericEnumStore; @@ -26,7 +26,7 @@ private: typedef EnumStoreT<NumericEntryType<float> > FloatEnumStore; typedef EnumStoreT<NumericEntryType<double> > DoubleEnumStore; - typedef EnumStoreBase::Index EnumIndex; + typedef IEnumStore::Index EnumIndex; typedef vespalib::GenerationHandler::generation_t generation_t; void testIndex(); @@ -445,7 +445,7 @@ EnumStoreTest::testCompaction(bool hasPostings) auto old_compaction_count = data_store_base.get_compaction_count(); // perform compaction - EnumStoreBase::EnumIndexMap old2New; + IEnumStore::EnumIndexMap old2New; EXPECT_TRUE(ses.performCompaction(3 * entrySize, old2New)); EXPECT_TRUE(ses.getRemaining() >= 3 * entrySize); EXPECT_TRUE(ses.getBuffer(1).remaining() >= 3 * entrySize); @@ -626,7 +626,7 @@ EnumStoreTest::testHoldListAndGeneration() // perform compaction uint32_t newEntrySize = StringEnumStore::alignEntrySize(8 + 1 + 8); - EnumStoreBase::EnumIndexMap old2New; + IEnumStore::EnumIndexMap old2New; EXPECT_TRUE(ses.performCompaction(5 * newEntrySize, old2New)); // check readers again @@ -715,7 +715,7 @@ EnumStoreTest::testMemoryUsage() EXPECT_EQUAL((num / 2) * entrySize + RESERVED_BYTES, usage.deadBytes()); EXPECT_EQUAL(0u, usage.allocatedBytesOnHold()); - EnumStoreBase::EnumIndexMap old2New; + IEnumStore::EnumIndexMap old2New; ses.performCompaction(400, old2New); // usage after compaction diff --git a/searchlib/src/tests/attribute/postinglistattribute/postinglistattribute_test.cpp b/searchlib/src/tests/attribute/postinglistattribute/postinglistattribute_test.cpp index 2d91ac7c689..505394b20ce 100644 --- a/searchlib/src/tests/attribute/postinglistattribute/postinglistattribute_test.cpp +++ b/searchlib/src/tests/attribute/postinglistattribute/postinglistattribute_test.cpp @@ -88,11 +88,11 @@ private: Int32PostingListAttribute; typedef MultiValueNumericPostingAttribute< EnumAttribute<IntegerAttributeTemplate<int32_t> >, - multivalue::Value<EnumStoreBase::Index> > + multivalue::Value<IEnumStore::Index> > Int32ArrayPostingListAttribute; typedef MultiValueNumericPostingAttribute< EnumAttribute<IntegerAttributeTemplate<int32_t> >, - multivalue::WeightedValue<EnumStoreBase::Index> > + multivalue::WeightedValue<IEnumStore::Index> > Int32WsetPostingListAttribute; typedef SingleValueNumericPostingAttribute< @@ -100,11 +100,11 @@ private: FloatPostingListAttribute; typedef MultiValueNumericPostingAttribute< EnumAttribute<FloatingPointAttributeTemplate<float> >, - multivalue::Value<EnumStoreBase::Index> > + multivalue::Value<IEnumStore::Index> > FloatArrayPostingListAttribute; typedef MultiValueNumericPostingAttribute< EnumAttribute<FloatingPointAttributeTemplate<float> >, - multivalue::WeightedValue<EnumStoreBase::Index> > + multivalue::WeightedValue<IEnumStore::Index> > FloatWsetPostingListAttribute; typedef SingleValueStringPostingAttribute StringPostingListAttribute; diff --git a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp index b7e036017ea..dcf246033ba 100644 --- a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp +++ b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp @@ -330,12 +330,12 @@ void StringAttributeTest::testDefaultValueOnAddDoc(AttributeVector & v) EXPECT_EQUAL(0u, v.getNumDocs()); v.addReservedDoc(); EXPECT_EQUAL(1u, v.getNumDocs()); - EXPECT_TRUE( EnumStoreBase::Index(EntryRef(v.getEnum(0))).valid() ); + EXPECT_TRUE( IEnumStore::Index(EntryRef(v.getEnum(0))).valid() ); uint32_t doc(7); EXPECT_TRUE( v.addDoc(doc) ); EXPECT_EQUAL(1u, doc); EXPECT_EQUAL(2u, v.getNumDocs()); - EXPECT_TRUE( EnumStoreBase::Index(EntryRef(v.getEnum(doc))).valid() ); + EXPECT_TRUE( IEnumStore::Index(EntryRef(v.getEnum(doc))).valid() ); EXPECT_EQUAL(0u, strlen(v.getString(doc, NULL, 0))); } @@ -357,7 +357,7 @@ StringAttributeTest::testSingleValue(Attribute & svsa, Config &cfg) EXPECT_TRUE( doc == i ); EXPECT_TRUE( v.getNumDocs() == i + 1 ); EXPECT_TRUE( v.getValueCount(doc) == 1 ); - EXPECT_TRUE( ! EnumStoreBase::Index(EntryRef(v.getEnum(doc))).valid() ); + EXPECT_TRUE( ! IEnumStore::Index(EntryRef(v.getEnum(doc))).valid() ); } std::map<vespalib::string, uint32_t> enums; @@ -366,7 +366,7 @@ StringAttributeTest::testSingleValue(Attribute & svsa, Config &cfg) sprintf(tmp, "enum%u", i % 10); EXPECT_TRUE( v.update(i, tmp) ); EXPECT_TRUE( v.getValueCount(i) == 1 ); - EXPECT_TRUE( ! EnumStoreBase::Index(EntryRef(v.getEnum(i))).valid() ); + EXPECT_TRUE( ! IEnumStore::Index(EntryRef(v.getEnum(i))).valid() ); if ((i % 10) == 9) { v.commit(); for (uint32_t j = i - 9; j <= i; ++j) { diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt index ea33a4d552c..286d10ef1c7 100644 --- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt @@ -41,7 +41,6 @@ vespa_add_library(searchlib_attribute OBJECT enumhintsearchcontext.cpp enum_store_dictionary.cpp enumstore.cpp - enumstorebase.cpp extendableattributes.cpp fixedsourceselector.cpp flagattribute.cpp @@ -59,7 +58,6 @@ vespa_add_library(searchlib_attribute OBJECT load_utils.cpp loadedenumvalue.cpp loadednumericvalue.cpp - loadedstringvalue.cpp loadedvalue.cpp multi_value_mapping.cpp multi_value_mapping_base.cpp diff --git a/searchlib/src/vespa/searchlib/attribute/address_space_usage.cpp b/searchlib/src/vespa/searchlib/attribute/address_space_usage.cpp index 4ad06fae54c..e03eec2764a 100644 --- a/searchlib/src/vespa/searchlib/attribute/address_space_usage.cpp +++ b/searchlib/src/vespa/searchlib/attribute/address_space_usage.cpp @@ -1,7 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "address_space_usage.h" -#include "enumstorebase.h" +#include "i_enum_store.h" namespace search { @@ -21,7 +21,7 @@ AddressSpaceUsage::AddressSpaceUsage(const AddressSpace &enumStoreUsage_, AddressSpace AddressSpaceUsage::defaultEnumStoreUsage() { - return AddressSpace(0, 0, EnumStoreBase::DataStoreType::RefType::offsetSize()); + return AddressSpace(0, 0, IEnumStore::Index::offsetSize()); } AddressSpace diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp index 3cefb665181..5d76aaf90f8 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp @@ -256,7 +256,7 @@ AttributeVector::headerTypeOK(const vespalib::GenericHeader &header) const void AttributeVector::removeOldGenerations(generation_t firstUsed) { (void) firstUsed; } void AttributeVector::onGenerationChange(generation_t generation) { (void) generation; } -const EnumStoreBase * AttributeVector::getEnumStoreBase() const { return nullptr; } +const IEnumStore * AttributeVector::getEnumStoreBase() const { return nullptr; } const attribute::MultiValueMappingBase * AttributeVector::getMultiValueBase() const { return nullptr; } std::unique_ptr<FastOS_FileInterface> diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.h b/searchlib/src/vespa/searchlib/attribute/attributevector.h index 20803ca2387..52e63385c7d 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributevector.h +++ b/searchlib/src/vespa/searchlib/attribute/attributevector.h @@ -43,7 +43,7 @@ namespace search { template <typename T> class ComponentGuard; class AttributeReadGuard; class AttributeSaver; - class EnumStoreBase; + class IEnumStore; class IAttributeSaveTarget; struct IDocumentWeightAttribute; class QueryTermSimple; @@ -550,7 +550,7 @@ public: attribute::ISearchContext::UP createSearchContext(QueryTermSimpleUP term, const attribute::SearchContextParams ¶ms) const override; virtual SearchContext::UP getSearch(QueryTermSimpleUP term, const attribute::SearchContextParams ¶ms) const = 0; - virtual const EnumStoreBase *getEnumStoreBase() const; + virtual const IEnumStore *getEnumStoreBase() const; virtual const attribute::MultiValueMappingBase *getMultiValueBase() const; private: diff --git a/searchlib/src/vespa/searchlib/attribute/defines.h b/searchlib/src/vespa/searchlib/attribute/defines.h index 649811eded2..1a7964e057b 100644 --- a/searchlib/src/vespa/searchlib/attribute/defines.h +++ b/searchlib/src/vespa/searchlib/attribute/defines.h @@ -5,7 +5,7 @@ #define ENUM_ATTRIBUTE(B) EnumAttribute<B> #define MULTIVALUE_ARG(T) multivalue::Value<T> -#define MULTIVALUE_ENUM_ARG multivalue::Value<EnumStoreBase::Index> +#define MULTIVALUE_ENUM_ARG multivalue::Value<IEnumStore::Index> #define WEIGHTED_MULTIVALUE_ARG(T) multivalue::WeightedValue<T> -#define WEIGHTED_MULTIVALUE_ENUM_ARG multivalue::WeightedValue<EnumStoreBase::Index> +#define WEIGHTED_MULTIVALUE_ENUM_ARG multivalue::WeightedValue<IEnumStore::Index> diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp index 690b267ec0c..24c0eeabd2c 100644 --- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp @@ -2,7 +2,6 @@ #include "enum_store_dictionary.h" #include "enumstore.h" -#include "enumstorebase.h" #include <vespa/vespalib/btree/btree.hpp> #include <vespa/vespalib/btree/btreeiterator.hpp> #include <vespa/vespalib/btree/btreenode.hpp> @@ -20,7 +19,7 @@ namespace search { using btree::BTreeNode; template <typename DictionaryT> -EnumStoreDictionary<DictionaryT>::EnumStoreDictionary(EnumStoreBase& enumStore) +EnumStoreDictionary<DictionaryT>::EnumStoreDictionary(IEnumStore& enumStore) : ParentUniqueStoreDictionary(), _enumStore(enumStore) { @@ -165,10 +164,10 @@ EnumStoreDictionary<DictionaryT>::findFrozenIndex(const datastore::EntryComparat } template <typename DictionaryT> -std::vector<EnumStoreBase::EnumHandle> +std::vector<IEnumStore::EnumHandle> EnumStoreDictionary<DictionaryT>::findMatchingEnums(const datastore::EntryComparator& cmp) const { - std::vector<EnumStoreBase::EnumHandle> result; + std::vector<IEnumStore::EnumHandle> result; auto itr = this->_dict.getFrozenView().find(Index(), cmp); while (itr.valid() && !cmp(Index(), itr.getKey())) { result.push_back(itr.getKey().ref()); @@ -225,94 +224,94 @@ template class EnumStoreDictionary<EnumTree>; template class EnumStoreDictionary<EnumPostingTree>; template -class btree::BTreeNodeT<EnumStoreBase::Index, EnumTreeTraits::INTERNAL_SLOTS>; +class btree::BTreeNodeT<IEnumStore::Index, EnumTreeTraits::INTERNAL_SLOTS>; template -class btree::BTreeNodeTT<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; +class btree::BTreeNodeTT<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; template -class btree::BTreeNodeTT<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeNodeTT<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeInternalNode<EnumStoreBase::Index, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; +class btree::BTreeInternalNode<IEnumStore::Index, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; template -class btree::BTreeLeafNode<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNode<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeLeafNode<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNode<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeLeafNodeTemp<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNodeTemp<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeLeafNodeTemp<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNodeTemp<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeNodeStore<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeNodeStore<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeNodeStore<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeNodeStore<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeRoot<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeRoot<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTreeRoot<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeRoot<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTreeRootT<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeRootT<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTreeRootT<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeRootT<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTreeRootBase<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeRootBase<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeRootBase<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeRootBase<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeNodeAllocator<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeNodeAllocator<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeNodeAllocator<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeNodeAllocator<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeIteratorBase<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeIteratorBase<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS, EnumTreeTraits::PATH_SIZE>; template -class btree::BTreeIteratorBase<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeIteratorBase<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS, EnumTreeTraits::PATH_SIZE>; -template class btree::BTreeConstIterator<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +template class btree::BTreeConstIterator<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; -template class btree::BTreeConstIterator<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +template class btree::BTreeConstIterator<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTreeIterator<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeIterator<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTreeIterator<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeIterator<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTree<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTree<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; template -class btree::BTree<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTree<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; } diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h index cd28f10a3cd..31f52e4e965 100644 --- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h +++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h @@ -7,7 +7,7 @@ namespace search { -class EnumStoreBase; +class IEnumStore; /** * Concrete dictionary for an enum store that extends the functionality of a unique store dictionary. @@ -22,10 +22,10 @@ private: using ParentUniqueStoreDictionary = datastore::UniqueStoreDictionary<DictionaryT, IEnumStoreDictionary>; using generation_t = IEnumStoreDictionary::generation_t; - EnumStoreBase& _enumStore; + IEnumStore& _enumStore; public: - EnumStoreDictionary(EnumStoreBase& enumStore); + EnumStoreDictionary(IEnumStore& enumStore); ~EnumStoreDictionary() override; @@ -63,95 +63,95 @@ public: }; extern template -class btree::BTreeNodeT<EnumStoreIndex, EnumTreeTraits::INTERNAL_SLOTS>; +class btree::BTreeNodeT<IEnumStore::Index, EnumTreeTraits::INTERNAL_SLOTS>; extern template -class btree::BTreeNodeTT<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; +class btree::BTreeNodeTT<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; extern template -class btree::BTreeNodeTT<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeNodeTT<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeInternalNode<EnumStoreIndex, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; +class btree::BTreeInternalNode<IEnumStore::Index, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS>; extern template -class btree::BTreeLeafNode<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNode<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeLeafNode<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNode<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeLeafNodeTemp<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNodeTemp<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeLeafNodeTemp<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; +class btree::BTreeLeafNodeTemp<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeNodeStore<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeNodeStore<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeNodeStore<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeNodeStore<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeRoot<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeRoot<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTreeRoot<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeRoot<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTreeRootT<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeRootT<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTreeRootT<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeRootT<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTreeRootBase<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeRootBase<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeRootBase<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeRootBase<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeNodeAllocator<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeNodeAllocator<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeNodeAllocator<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeNodeAllocator<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeIteratorBase<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeIteratorBase<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS, EnumTreeTraits::PATH_SIZE>; extern template -class btree::BTreeIteratorBase<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeIteratorBase<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS, EnumTreeTraits::PATH_SIZE>; -extern template class btree::BTreeConstIterator<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +extern template class btree::BTreeConstIterator<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; -extern template class btree::BTreeConstIterator<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +extern template class btree::BTreeConstIterator<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTreeIterator<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeIterator<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTreeIterator<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeIterator<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTree<EnumStoreIndex, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTree<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; extern template -class btree::BTree<EnumStoreIndex, datastore::EntryRef, btree::NoAggregated, +class btree::BTree<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; diff --git a/searchlib/src/vespa/searchlib/attribute/enumattribute.h b/searchlib/src/vespa/searchlib/attribute/enumattribute.h index 0c8ef800648..55af5a874f9 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/enumattribute.h @@ -5,6 +5,7 @@ #include "attributevector.h" #include "loadedenumvalue.h" #include "enumstore.h" +#include "no_loaded_vector.h" #include <set> namespace search { @@ -51,15 +52,15 @@ public: using EnumStoreBatchUpdater = typename EnumStore::BatchUpdater; protected: - using EnumIndex = EnumStoreBase::Index; - using EnumIndexMap = EnumStoreBase::EnumIndexMap; + using EnumIndex = IEnumStore::Index; + using EnumIndexMap = IEnumStore::EnumIndexMap; EnumStore _enumStore; EnumStore & getEnumStore() { return _enumStore; } const EnumStore & getEnumStore() const { return _enumStore; } - const EnumStoreBase * getEnumStoreBase() const override { return &_enumStore; } + const IEnumStore* getEnumStoreBase() const override { return &_enumStore; } EnumType getFromEnum(EnumHandle e) const override { return _enumStore.getValue(e); } void fillPostings(LoadedVector & loaded) override { (void) loaded; } diff --git a/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp index 1268e7d3118..a5ba60cad4d 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp @@ -26,28 +26,30 @@ EnumAttribute<B>::~EnumAttribute() template <typename B> void EnumAttribute<B>::fillEnum(LoadedVector & loaded) { - typename EnumStore::Builder builder; - if (!loaded.empty()) { - auto value = loaded.read(); - LoadedValueType prev = value.getValue(); - uint32_t prevRefCount(0); - EnumIndex index = builder.insert(value.getValue(), value._pidx.ref()); - for (size_t i(0), m(loaded.size()); i < m; ++i, loaded.next()) { - value = loaded.read(); - if (EnumStore::ComparatorType::compare(prev, value.getValue()) != 0) { - builder.updateRefCount(prevRefCount); - index = builder.insert(value.getValue(), value._pidx.ref()); - prev = value.getValue(); - prevRefCount = 1; - } else { - prevRefCount++; + if constexpr(!std::is_same_v<LoadedVector, NoLoadedVector>) { + typename EnumStore::Builder builder; + if (!loaded.empty()) { + auto value = loaded.read(); + LoadedValueType prev = value.getValue(); + uint32_t prevRefCount(0); + EnumIndex index = builder.insert(value.getValue(), value._pidx.ref()); + for (size_t i(0), m(loaded.size()); i < m; ++i, loaded.next()) { + value = loaded.read(); + if (EnumStore::ComparatorType::compare(prev, value.getValue()) != 0) { + builder.updateRefCount(prevRefCount); + index = builder.insert(value.getValue(), value._pidx.ref()); + prev = value.getValue(); + prevRefCount = 1; + } else { + prevRefCount++; + } + value.setEidx(index); + loaded.write(value); } - value.setEidx(index); - loaded.write(value); + builder.updateRefCount(prevRefCount); } - builder.updateRefCount(prevRefCount); + _enumStore.reset(builder); } - _enumStore.reset(builder); } diff --git a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp index 75cd504faad..db235f91798 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "enumattributesaver.h" +#include "i_enum_store_dictionary.h" #include "iattributesavetarget.h" #include <vespa/vespalib/util/bufferwriter.h> #include <vespa/vespalib/datastore/unique_store_enumerator.hpp> @@ -8,7 +9,7 @@ namespace search { EnumAttributeSaver:: -EnumAttributeSaver(const EnumStoreBase &enumStore) +EnumAttributeSaver(const IEnumStore &enumStore) : _enumStore(enumStore), _enumerator(_enumStore.getEnumStoreDict(), _enumStore.get_data_store_base()) { @@ -34,6 +35,6 @@ EnumAttributeSaver::writeUdat(IAttributeSaveTarget &saveTarget) namespace search::datastore { -template class UniqueStoreEnumerator<EnumStoreIndex>; +template class UniqueStoreEnumerator<IEnumStore::Index>; } diff --git a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h index 9c703c4f72c..c399a0a88b1 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h +++ b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h @@ -2,14 +2,14 @@ #pragma once -#include "enumstorebase.h" +#include "i_enum_store.h" #include <vespa/vespalib/datastore/unique_store_enumerator.h> namespace search { class IAttributeSaveTarget; -/* +/** * Helper class for saving an enumerated multivalue attribute. * * It handles writing to the udat file. @@ -17,18 +17,18 @@ class IAttributeSaveTarget; class EnumAttributeSaver { public: - using Enumerator = datastore::UniqueStoreEnumerator<EnumStoreIndex>; + using Enumerator = datastore::UniqueStoreEnumerator<IEnumStore::Index>; private: - const EnumStoreBase &_enumStore; + const IEnumStore &_enumStore; Enumerator _enumerator; public: - EnumAttributeSaver(const EnumStoreBase &enumStore); + EnumAttributeSaver(const IEnumStore &enumStore); ~EnumAttributeSaver(); void writeUdat(IAttributeSaveTarget &saveTarget); - const EnumStoreBase &getEnumStore() const { return _enumStore; } + const IEnumStore &getEnumStore() const { return _enumStore; } Enumerator &get_enumerator() { return _enumerator; } void clear() { _enumerator.clear(); } }; diff --git a/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.cpp b/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.cpp index f221ac858bd..28a270555d3 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.cpp @@ -25,15 +25,15 @@ EnumHintSearchContext::~EnumHintSearchContext() = default; void -EnumHintSearchContext::lookupTerm(const EnumStoreComparator &comp) +EnumHintSearchContext::lookupTerm(const datastore::EntryComparator &comp) { _uniqueValues = _dict_snapshot->count(comp); } void -EnumHintSearchContext::lookupRange(const EnumStoreComparator &low, - const EnumStoreComparator &high) +EnumHintSearchContext::lookupRange(const datastore::EntryComparator &low, + const datastore::EntryComparator &high) { _uniqueValues = _dict_snapshot->count_in_range(low, high); } diff --git a/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h b/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h index 6f766bec386..5a20318ae7b 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h +++ b/searchlib/src/vespa/searchlib/attribute/enumhintsearchcontext.h @@ -2,11 +2,15 @@ #pragma once -#include "enumstore.h" +#include "i_enum_store_dictionary.h" #include "ipostinglistsearchcontext.h" #include <vespa/searchlib/queryeval/searchiterator.h> -namespace search::attribute { +namespace search { + +namespace datastore { class EntryComparator; } + +namespace attribute { /** * Search context helper for enumerated attributes, used to eliminate @@ -19,16 +23,16 @@ class EnumHintSearchContext : public IPostingListSearchContext uint32_t _uniqueValues; uint32_t _docIdLimit; uint64_t _numValues; // attr.getStatus().getNumValues(); - + protected: EnumHintSearchContext(const IEnumStoreDictionary &dictionary, uint32_t docIdLimit, uint64_t numValues); ~EnumHintSearchContext(); - void lookupTerm(const EnumStoreComparator &comp); - void lookupRange(const EnumStoreComparator &low, const EnumStoreComparator &high); - + void lookupTerm(const datastore::EntryComparator &comp); + void lookupRange(const datastore::EntryComparator &low, const datastore::EntryComparator &high); + queryeval::SearchIterator::UP createPostingIterator(fef::TermFieldMatchData *matchData, bool strict) override; @@ -37,3 +41,4 @@ protected: }; } +} diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.cpp b/searchlib/src/vespa/searchlib/attribute/enumstore.cpp index de695532f42..4cf5ea9c766 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.cpp @@ -1,6 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "enumstore.hpp" +#include <vespa/vespalib/stllike/hash_map.hpp> +#include <vespa/vespalib/util/rcuvector.hpp> #include <iomanip> #include <vespa/log/log.h> @@ -82,12 +84,18 @@ EnumStoreT<StringEntryType>::deserialize(const void *src, return sz; } +vespalib::asciistream & operator << (vespalib::asciistream & os, const IEnumStore::Index & idx) { + return os << "offset(" << idx.offset() << "), bufferId(" << idx.bufferId() << "), idx(" << idx.ref() << ")"; +} + +template class datastore::DataStoreT<IEnumStore::Index>; + template -class btree::BTreeBuilder<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeBuilder<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template -class btree::BTreeBuilder<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeBuilder<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; template class EnumStoreT< StringEntryType >; @@ -99,3 +107,11 @@ template class EnumStoreT<NumericEntryType<float> >; template class EnumStoreT<NumericEntryType<double> >; } // namespace search + +namespace vespalib { + template class RcuVectorBase<search::IEnumStore::Index>; +} + +VESPALIB_HASH_MAP_INSTANTIATE_H_E_M(search::IEnumStore::Index, search::IEnumStore::Index, + vespalib::hash<search::IEnumStore::Index>, std::equal_to<search::IEnumStore::Index>, + vespalib::hashtable_base::and_modulator); diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.h b/searchlib/src/vespa/searchlib/attribute/enumstore.h index 56bf257b046..fa5e9611c55 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.h +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.h @@ -3,7 +3,7 @@ #pragma once #include "enum_store_dictionary.h" -#include "enumstorebase.h" +#include "i_enum_store.h" #include <vespa/searchlib/util/foldedstringcompare.h> #include <vespa/vespalib/btree/btreenode.h> #include <vespa/vespalib/btree/btreenodeallocator.h> @@ -74,7 +74,7 @@ struct FloatingPointCompareHelper // EnumStoreT //----------------------------------------------------------------------------- template <class EntryType> -class EnumStoreT : public EnumStoreBase +class EnumStoreT : public IEnumStore { friend class EnumStoreTest; public: @@ -82,9 +82,31 @@ public: using ComparatorType = EnumStoreComparatorT<EntryType>; using FoldedComparatorType = EnumStoreFoldedComparatorT<EntryType>; using EnumStoreType = EnumStoreT<EntryType>; - using EnumStoreBase::deserialize; - using EnumStoreBase::fixupRefCounts; - using EnumStoreBase::reset; + using DataStoreType = datastore::DataStoreT<Index>; + using generation_t = vespalib::GenerationHandler::generation_t; + + class EntryBase { + protected: + char * _data; + public: + EntryBase(void * data) : _data(static_cast<char *>(data)) {} + uint32_t getRefCount() const { + return *(reinterpret_cast<uint32_t *>(_data) + 1); + } + void incRefCount() { + uint32_t *dst = reinterpret_cast<uint32_t *>(_data) + 1; + ++(*dst); + } + void decRefCount() { + uint32_t *dst = reinterpret_cast<uint32_t *>(_data) + 1; + --(*dst); + } + void setRefCount(uint32_t refCount) { + uint32_t *dst = reinterpret_cast<uint32_t *>(_data) + 1; + *dst = refCount; + } + static uint32_t size() { return 2*sizeof(uint32_t); } + }; class Entry : public EntryBase { public: @@ -92,9 +114,40 @@ public: Type getValue() const; static uint32_t fixedSize() { return EntryBase::size() + EntryType::fixedSize(); } }; + + class EnumBufferType : public datastore::BufferType<char> { + private: + size_t _minSizeNeeded; // lower cap for sizeNeeded + size_t _deadElems; // dead elements in active buffer + bool _pendingCompact; + bool _wantCompact; + public: + EnumBufferType(); + size_t calcArraysToAlloc(uint32_t bufferId, size_t sizeNeeded, bool resizing) const override; + void setSizeNeededAndDead(size_t sizeNeeded, size_t deadElems) { + _minSizeNeeded = sizeNeeded; + _deadElems = deadElems; + } + void onFree(size_t usedElems) override { + datastore::BufferType<char>::onFree(usedElems); + _pendingCompact = _wantCompact; + _wantCompact = false; + } + void setWantCompact() { _wantCompact = true; } + bool getPendingCompact() const { return _pendingCompact; } + void clearPendingCompact() { _pendingCompact = false; } + }; + static void insertEntry(char * dst, uint32_t refCount, Type value); private: + IEnumStoreDictionary *_enumDict; + DataStoreType _store; + EnumBufferType _type; + std::vector<uint32_t> _toHoldBuffers; // used during compaction + + static const uint32_t TYPE_ID = 0; + EnumStoreT(const EnumStoreT & rhs) = delete; EnumStoreT & operator=(const EnumStoreT & rhs) = delete; @@ -102,10 +155,21 @@ private: memcpy(dst, &value, sizeof(Type)); } -protected: - typedef EnumStoreBase::IndexSet IndexSet; - using EnumStoreBase::_store; - using EnumStoreBase::TYPE_ID; + EntryBase getEntryBase(Index idx) const { + return EntryBase(const_cast<DataStoreType &>(_store).getEntry<char>(idx)); + } + datastore::BufferState & getBuffer(uint32_t bufferIdx) { + return _store.getBufferState(bufferIdx); + } + const datastore::BufferState & getBuffer(uint32_t bufferIdx) const { + return _store.getBufferState(bufferIdx); + } + bool validIndex(Index idx) const { + return (idx.valid() && idx.offset() < _store.getBufferState(idx.bufferId()).size()); + } + uint32_t getBufferIndex(datastore::BufferState::State status); + void postCompact(); + bool preCompact(uint64_t bytesNeeded); Entry getEntry(Index idx) const { return Entry(const_cast<DataStoreType &>(_store).getEntry<char>(idx)); @@ -114,18 +178,70 @@ protected: void freeUnusedEnum(Index idx, IndexSet & unused) override; public: - EnumStoreT(uint64_t initBufferSize, bool hasPostings) - : EnumStoreBase(initBufferSize, hasPostings) - { + EnumStoreT(uint64_t initBufferSize, bool hasPostings); + virtual ~EnumStoreT(); + + void reset(uint64_t initBufferSize); + + uint32_t getRefCount(Index idx) const { return getEntryBase(idx).getRefCount(); } + void incRefCount(Index idx) { getEntryBase(idx).incRefCount(); } + void decRefCount(Index idx) { getEntryBase(idx).decRefCount(); } + + // Only use when reading from enumerated attribute save files + void fixupRefCount(Index idx, uint32_t refCount) override { + getEntryBase(idx).setRefCount(refCount); + } + + uint32_t getNumUniques() const override { return _enumDict->getNumUniques(); } + + uint32_t getRemaining() const { + return _store.getBufferState(_store.getActiveBufferId(TYPE_ID)).remaining(); + } + uint32_t getCapacity() const { + return _store.getBufferState(_store.getActiveBufferId(TYPE_ID)).capacity(); + } + vespalib::MemoryUsage getMemoryUsage() const override { return _store.getMemoryUsage(); } + vespalib::MemoryUsage getTreeMemoryUsage() const override { return _enumDict->get_memory_usage(); } + + vespalib::AddressSpace getAddressSpaceUsage() const; + + void transferHoldLists(generation_t generation); + void trimHoldLists(generation_t firstUsed); + + static void failNewSize(uint64_t minNewSize, uint64_t maxSize); + + // Align buffers and entries to 4 bytes boundary. + static uint64_t alignBufferSize(uint64_t val) { return Index::align(val); } + static uint32_t alignEntrySize(uint32_t val) { return Index::align(val); } + + void fallbackResize(uint64_t bytesNeeded); + bool getPendingCompact() const { return _type.getPendingCompact(); } + void clearPendingCompact() { _type.clearPendingCompact(); } + + ssize_t deserialize0(const void *src, size_t available, IndexVector &idx) override; + + ssize_t deserialize(const void *src, size_t available, IndexVector &idx) { + return _enumDict->deserialize(src, available, idx); + } + + void fixupRefCounts(const EnumVector &hist) { _enumDict->fixupRefCounts(hist); } + void freezeTree() { _enumDict->freeze(); } + + IEnumStoreDictionary &getEnumStoreDict() override { return *_enumDict; } + const IEnumStoreDictionary &getEnumStoreDict() const override { return *_enumDict; } + EnumPostingTree &getPostingDictionary() { return _enumDict->getPostingDictionary(); } + + const EnumPostingTree &getPostingDictionary() const { + return _enumDict->getPostingDictionary(); } + const datastore::DataStoreBase &get_data_store_base() const override { return _store; } + bool getValue(Index idx, Type & value) const; Type getValue(uint32_t idx) const { return getValue(Index(datastore::EntryRef(idx))); } Type getValue(Index idx) const { return getEntry(idx).getValue(); } - static uint32_t - getEntrySize(Type value) - { + static uint32_t getEntrySize(Type value) { return alignEntrySize(EntryBase::size() + EntryType::size(value)); } @@ -192,17 +308,17 @@ public: } void writeValues(BufferWriter &writer, const Index *idxs, size_t count) const override; - ssize_t deserialize(const void *src, size_t available, size_t &initSpace) override; - ssize_t deserialize(const void *src, size_t available, Index &idx) override; + ssize_t deserialize(const void *src, size_t available, size_t &initSpace); + ssize_t deserialize(const void *src, size_t available, Index &idx); bool foldedChange(const Index &idx1, const Index &idx2) override; - virtual bool findEnum(Type value, EnumStoreBase::EnumHandle &e) const; - virtual std::vector<EnumStoreBase::EnumHandle> findFoldedEnums(Type value) const; + virtual bool findEnum(Type value, IEnumStore::EnumHandle &e) const; + virtual std::vector<IEnumStore::EnumHandle> findFoldedEnums(Type value) const; void addEnum(Type value, Index &newIdx); virtual bool findIndex(Type value, Index &idx) const; void freeUnusedEnums(bool movePostingidx) override; - void freeUnusedEnums(const IndexSet& toRemove) override; + void freeUnusedEnums(const IndexSet& toRemove); void reset(Builder &builder); - bool performCompaction(uint64_t bytesNeeded, EnumIndexMap & old2New) override; + bool performCompaction(uint64_t bytesNeeded, EnumIndexMap & old2New); private: template <typename Dictionary> @@ -215,12 +331,18 @@ private: void performCompaction(Dictionary &dict, EnumIndexMap & old2New); }; +vespalib::asciistream & operator << (vespalib::asciistream & os, const IEnumStore::Index & idx); + +extern template +class datastore::DataStoreT<IEnumStore::Index>; + + template <typename EntryType> inline typename EntryType::Type EnumStoreT<EntryType>::Entry::getValue() const // implementation for numeric { Type dst; - const char * src = _data + EntryBase::size(); + const char * src = this->_data + EntryBase::size(); memcpy(&dst, src, sizeof(Type)); return dst; } @@ -263,10 +385,10 @@ insertEntryValue(char * dst, Type value); extern template -class btree::BTreeBuilder<EnumStoreBase::Index, btree::BTreeNoLeafData, btree::NoAggregated, +class btree::BTreeBuilder<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template -class btree::BTreeBuilder<EnumStoreBase::Index, datastore::EntryRef, btree::NoAggregated, +class btree::BTreeBuilder<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, EnumTreeTraits::INTERNAL_SLOTS, EnumTreeTraits::LEAF_SLOTS>; extern template class EnumStoreT< StringEntryType >; diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp index 4627c7bc03e..428875e00db 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp @@ -5,6 +5,7 @@ #include "enumstore.h" #include "enumcomparator.h" +#include <vespa/vespalib/util/exceptions.h> #include <vespa/vespalib/util/hdr_abort.h> #include <vespa/vespalib/btree/btreenode.hpp> #include <vespa/vespalib/btree/btreenodestore.hpp> @@ -25,15 +26,49 @@ const uint32_t dummy_enum_value = 0; } template <typename EntryType> -void EnumStoreT<EntryType>::freeUnusedEnum(Index idx, IndexSet & unused) +EnumStoreT<EntryType>::EnumBufferType::EnumBufferType() + : datastore::BufferType<char>(Index::align(1), + Index::offsetSize() / Index::align(1), + Index::offsetSize() / Index::align(1)), + _minSizeNeeded(0), + _deadElems(0), + _pendingCompact(false), + _wantCompact(false) { - Entry e = getEntry(idx); - if (e.getRefCount() == 0) { - Type value = e.getValue(); - if (unused.insert(idx).second) { - _store.incDead(idx, getEntrySize(value)); - } +} + +template <typename EntryType> +size_t +EnumStoreT<EntryType>::EnumBufferType::calcArraysToAlloc(uint32_t bufferId, size_t sizeNeeded, bool resizing) const +{ + (void) resizing; + size_t reservedElements = getReservedElements(bufferId); + sizeNeeded = std::max(sizeNeeded, _minSizeNeeded); + size_t usedElems = _activeUsedElems; + if (_lastUsedElems != nullptr) { + usedElems += *_lastUsedElems; + } + assert((usedElems % _arraySize) == 0); + double growRatio = 1.5f; + uint64_t maxSize = static_cast<uint64_t>(_maxArrays) * _arraySize; + uint64_t newSize = usedElems - _deadElems + sizeNeeded; + if (usedElems != 0) { + newSize *= growRatio; } + newSize += reservedElements; + newSize = alignBufferSize(newSize); + assert((newSize % _arraySize) == 0); + if (newSize <= maxSize) { + return newSize / _arraySize; + } + newSize = usedElems - _deadElems + sizeNeeded + reservedElements + 1000000; + newSize = alignBufferSize(newSize); + assert((newSize % _arraySize) == 0); + if (newSize <= maxSize) { + return _maxArrays; + } + failNewSize(newSize, maxSize); + return 0; } template <typename EntryType> @@ -54,6 +89,161 @@ EnumStoreT<StringEntryType>:: insertEntryValue(char * dst, Type value); template <typename EntryType> +uint32_t +EnumStoreT<EntryType>::getBufferIndex(datastore::BufferState::State status) +{ + for (uint32_t i = 0; i < _store.getNumBuffers(); ++i) { + if (_store.getBufferState(i).getState() == status) { + return i; + } + } + return Index::numBuffers(); +} + +template <typename EntryType> +void +EnumStoreT<EntryType>::postCompact() +{ + _store.finishCompact(_toHoldBuffers); +} + +template <typename EntryType> +bool +EnumStoreT<EntryType>::preCompact(uint64_t bytesNeeded) +{ + if (getBufferIndex(datastore::BufferState::FREE) == Index::numBuffers()) { + return false; + } + uint32_t activeBufId = _store.getActiveBufferId(TYPE_ID); + datastore::BufferState & activeBuf = _store.getBufferState(activeBufId); + _type.setSizeNeededAndDead(bytesNeeded, activeBuf.getDeadElems()); + _toHoldBuffers = _store.startCompact(TYPE_ID); + return true; +} + +template <typename EntryType> +void EnumStoreT<EntryType>::freeUnusedEnum(Index idx, IndexSet & unused) +{ + Entry e = getEntry(idx); + if (e.getRefCount() == 0) { + Type value = e.getValue(); + if (unused.insert(idx).second) { + _store.incDead(idx, getEntrySize(value)); + } + } +} + +template <typename EntryType> +EnumStoreT<EntryType>::EnumStoreT(uint64_t initBufferSize, bool hasPostings) + : _enumDict(nullptr), + _store(), + _type(), + _toHoldBuffers() +{ + if (hasPostings) { + _enumDict = new EnumStoreDictionary<EnumPostingTree>(*this); + } else { + _enumDict = new EnumStoreDictionary<EnumTree>(*this); + } + _store.addType(&_type); + _type.setSizeNeededAndDead(initBufferSize, 0); + _store.initActiveBuffers(); +} + +template <typename EntryType> +EnumStoreT<EntryType>::~EnumStoreT() +{ + _store.clearHoldLists(); + _store.dropBuffers(); + delete _enumDict; +} + +template <typename EntryType> +void +EnumStoreT<EntryType>::reset(uint64_t initBufferSize) +{ + _store.clearHoldLists(); + _store.dropBuffers(); + _type.setSizeNeededAndDead(initBufferSize, 0); + _store.initActiveBuffers(); + _enumDict->onReset(); +} + +template <typename EntryType> +vespalib::AddressSpace +EnumStoreT<EntryType>::getAddressSpaceUsage() const +{ + const datastore::BufferState &activeState = _store.getBufferState(_store.getActiveBufferId(TYPE_ID)); + return vespalib::AddressSpace(activeState.size(), activeState.getDeadElems(), DataStoreType::RefType::offsetSize()); +} + +template <typename EntryType> +void +EnumStoreT<EntryType>::transferHoldLists(generation_t generation) +{ + _enumDict->transfer_hold_lists(generation); + _store.transferHoldLists(generation); +} + +template <typename EntryType> +void +EnumStoreT<EntryType>::trimHoldLists(generation_t firstUsed) +{ + // remove generations in the range [0, firstUsed> + _enumDict->trim_hold_lists(firstUsed); + _store.trimHoldLists(firstUsed); +} + +template <typename EntryType> +void +EnumStoreT<EntryType>::failNewSize(uint64_t minNewSize, uint64_t maxSize) +{ + throw vespalib::IllegalStateException(vespalib::make_string("EnumStoreT::failNewSize: Minimum new size (%" PRIu64 ") exceeds max size (%" PRIu64 ")", minNewSize, maxSize)); +} + +template <typename EntryType> +void +EnumStoreT<EntryType>::fallbackResize(uint64_t bytesNeeded) +{ + uint32_t activeBufId = _store.getActiveBufferId(TYPE_ID); + size_t reservedElements = _type.getReservedElements(activeBufId); + _type.setSizeNeededAndDead(bytesNeeded, reservedElements); + _type.setWantCompact(); + _store.fallbackResize(activeBufId, bytesNeeded); +} + +template <typename EntryType> +ssize_t +EnumStoreT<EntryType>::deserialize0(const void *src, + size_t available, + IndexVector &idx) +{ + size_t left = available; + size_t initSpace = Index::align(1); + const char * p = static_cast<const char *>(src); + while (left > 0) { + ssize_t sz = deserialize(p, left, initSpace); + if (sz < 0) + return sz; + p += sz; + left -= sz; + } + reset(initSpace); + left = available; + p = static_cast<const char *>(src); + Index idx1; + while (left > 0) { + ssize_t sz = deserialize(p, left, idx1); + if (sz < 0) + return sz; + p += sz; + left -= sz; + idx.push_back(idx1); + } + return available - left; +} + +template <typename EntryType> bool EnumStoreT<EntryType>::getValue(Index idx, Type & value) const { @@ -142,7 +332,7 @@ EnumStoreT<EntryType>::foldedChange(const Index &idx1, const Index &idx2) template <typename EntryType> bool -EnumStoreT<EntryType>::findEnum(Type value, EnumStoreBase::EnumHandle &e) const +EnumStoreT<EntryType>::findEnum(Type value, IEnumStore::EnumHandle &e) const { ComparatorType cmp(*this, value); Index idx; @@ -154,7 +344,7 @@ EnumStoreT<EntryType>::findEnum(Type value, EnumStoreBase::EnumHandle &e) const } template <typename EntryType> -std::vector<EnumStoreBase::EnumHandle> +std::vector<IEnumStore::EnumHandle> EnumStoreT<EntryType>::findFoldedEnums(Type value) const { FoldedComparatorType cmp(*this, value); @@ -283,7 +473,7 @@ EnumStoreT<EntryType>::addEnum(Type value, Index & newIdx) template <typename DictionaryType> struct TreeBuilderInserter { static void insert(typename DictionaryType::Builder & builder, - EnumStoreBase::Index enumIdx, + IEnumStore::Index enumIdx, datastore::EntryRef postingIdx) { (void) postingIdx; @@ -294,7 +484,7 @@ struct TreeBuilderInserter { template <> struct TreeBuilderInserter<EnumPostingTree> { static void insert(EnumPostingTree::Builder & builder, - EnumStoreBase::Index enumIdx, + IEnumStore::Index enumIdx, datastore::EntryRef postingIdx) { builder.insert(enumIdx, postingIdx); @@ -308,7 +498,7 @@ void EnumStoreT<EntryType>::reset(Builder &builder, Dictionary &dict) { typedef typename Dictionary::Builder DictionaryBuilder; - EnumStoreBase::reset(builder.getBufferSize()); + reset(builder.getBufferSize()); DictionaryBuilder treeBuilder(dict.getAllocator()); uint32_t activeBufferId = _store.getActiveBufferId(TYPE_ID); diff --git a/searchlib/src/vespa/searchlib/attribute/enumstorebase.cpp b/searchlib/src/vespa/searchlib/attribute/enumstorebase.cpp deleted file mode 100644 index 71b55689048..00000000000 --- a/searchlib/src/vespa/searchlib/attribute/enumstorebase.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "enumstorebase.h" -#include "enumstore.h" -#include "enum_store_dictionary.h" -#include <vespa/vespalib/btree/btree.hpp> -#include <vespa/vespalib/btree/btreeiterator.hpp> -#include <vespa/vespalib/btree/btreenode.hpp> -#include <vespa/vespalib/btree/btreenodeallocator.hpp> -#include <vespa/vespalib/btree/btreeroot.hpp> -#include <vespa/vespalib/datastore/datastore.hpp> -#include <vespa/vespalib/datastore/unique_store_dictionary.hpp> -#include <vespa/vespalib/stllike/asciistream.h> -#include <vespa/vespalib/stllike/hash_map.hpp> -#include <vespa/vespalib/util/bufferwriter.h> -#include <vespa/vespalib/util/exceptions.h> -#include <vespa/vespalib/util/rcuvector.hpp> - - -#include <vespa/log/log.h> -LOG_SETUP(".searchlib.attribute.enumstorebase"); - -namespace search { - -using btree::BTreeNode; - -EnumStoreBase::EnumBufferType::EnumBufferType() - : datastore::BufferType<char>(Index::align(1), - Index::offsetSize() / Index::align(1), - Index::offsetSize() / Index::align(1)), - _minSizeNeeded(0), - _deadElems(0), - _pendingCompact(false), - _wantCompact(false) -{ -} - -size_t -EnumStoreBase::EnumBufferType::calcArraysToAlloc(uint32_t bufferId, size_t sizeNeeded, bool resizing) const -{ - (void) resizing; - size_t reservedElements = getReservedElements(bufferId); - sizeNeeded = std::max(sizeNeeded, _minSizeNeeded); - size_t usedElems = _activeUsedElems; - if (_lastUsedElems != nullptr) { - usedElems += *_lastUsedElems; - } - assert((usedElems % _arraySize) == 0); - double growRatio = 1.5f; - uint64_t maxSize = static_cast<uint64_t>(_maxArrays) * _arraySize; - uint64_t newSize = usedElems - _deadElems + sizeNeeded; - if (usedElems != 0) { - newSize *= growRatio; - } - newSize += reservedElements; - newSize = alignBufferSize(newSize); - assert((newSize % _arraySize) == 0); - if (newSize <= maxSize) { - return newSize / _arraySize; - } - newSize = usedElems - _deadElems + sizeNeeded + reservedElements + 1000000; - newSize = alignBufferSize(newSize); - assert((newSize % _arraySize) == 0); - if (newSize <= maxSize) { - return _maxArrays; - } - failNewSize(newSize, maxSize); - return 0; -} - -EnumStoreBase::EnumStoreBase(uint64_t initBufferSize, bool hasPostings) - : _enumDict(nullptr), - _store(), - _type(), - _toHoldBuffers() -{ - if (hasPostings) - _enumDict = new EnumStoreDictionary<EnumPostingTree>(*this); - else - _enumDict = new EnumStoreDictionary<EnumTree>(*this); - _store.addType(&_type); - _type.setSizeNeededAndDead(initBufferSize, 0); - _store.initActiveBuffers(); -} - -EnumStoreBase::~EnumStoreBase() -{ - _store.clearHoldLists(); - _store.dropBuffers(); - delete _enumDict; -} - -void -EnumStoreBase::reset(uint64_t initBufferSize) -{ - _store.clearHoldLists(); - _store.dropBuffers(); - _type.setSizeNeededAndDead(initBufferSize, 0); - _store.initActiveBuffers(); - _enumDict->onReset(); -} - -uint32_t -EnumStoreBase::getBufferIndex(datastore::BufferState::State status) -{ - for (uint32_t i = 0; i < _store.getNumBuffers(); ++i) { - if (_store.getBufferState(i).getState() == status) { - return i; - } - } - return Index::numBuffers(); -} - -vespalib::MemoryUsage -EnumStoreBase::getMemoryUsage() const -{ - return _store.getMemoryUsage(); -} - -vespalib::AddressSpace -EnumStoreBase::getAddressSpaceUsage() const -{ - const datastore::BufferState &activeState = _store.getBufferState(_store.getActiveBufferId(TYPE_ID)); - return vespalib::AddressSpace(activeState.size(), activeState.getDeadElems(), DataStoreType::RefType::offsetSize()); -} - -void -EnumStoreBase::transferHoldLists(generation_t generation) -{ - _enumDict->transfer_hold_lists(generation); - _store.transferHoldLists(generation); -} - -void -EnumStoreBase::trimHoldLists(generation_t firstUsed) -{ - // remove generations in the range [0, firstUsed> - _enumDict->trim_hold_lists(firstUsed); - _store.trimHoldLists(firstUsed); -} - -bool -EnumStoreBase::preCompact(uint64_t bytesNeeded) -{ - if (getBufferIndex(datastore::BufferState::FREE) == Index::numBuffers()) { - return false; - } - uint32_t activeBufId = _store.getActiveBufferId(TYPE_ID); - datastore::BufferState & activeBuf = _store.getBufferState(activeBufId); - _type.setSizeNeededAndDead(bytesNeeded, activeBuf.getDeadElems()); - _toHoldBuffers = _store.startCompact(TYPE_ID); - return true; -} - - -void -EnumStoreBase::fallbackResize(uint64_t bytesNeeded) -{ - uint32_t activeBufId = _store.getActiveBufferId(TYPE_ID); - size_t reservedElements = _type.getReservedElements(activeBufId); - _type.setSizeNeededAndDead(bytesNeeded, reservedElements); - _type.setWantCompact(); - _store.fallbackResize(activeBufId, bytesNeeded); -} - - -void -EnumStoreBase::postCompact() -{ - _store.finishCompact(_toHoldBuffers); -} - -void -EnumStoreBase::failNewSize(uint64_t minNewSize, uint64_t maxSize) -{ - throw vespalib::IllegalStateException(vespalib::make_string("EnumStoreBase::failNewSize: Minimum new size (%" PRIu64 ") exceeds max size (%" PRIu64 ")", minNewSize, maxSize)); -} - -ssize_t -EnumStoreBase::deserialize0(const void *src, - size_t available, - IndexVector &idx) -{ - size_t left = available; - size_t initSpace = Index::align(1); - const char * p = static_cast<const char *>(src); - while (left > 0) { - ssize_t sz = deserialize(p, left, initSpace); - if (sz < 0) - return sz; - p += sz; - left -= sz; - } - reset(initSpace); - left = available; - p = static_cast<const char *>(src); - Index idx1; - while (left > 0) { - ssize_t sz = deserialize(p, left, idx1); - if (sz < 0) - return sz; - p += sz; - left -= sz; - idx.push_back(idx1); - } - return available - left; -} - - -template <typename Tree> -ssize_t -EnumStoreBase::deserialize(const void *src, - size_t available, - IndexVector &idx, - Tree &tree) -{ - ssize_t sz(deserialize0(src, available, idx)); - if (sz >= 0) { - typename Tree::Builder builder(tree.getAllocator()); - typedef IndexVector::const_iterator IT; - for (IT i(idx.begin()), ie(idx.end()); i != ie; ++i) { - builder.insert(*i, typename Tree::DataType()); - } - tree.assign(builder); - } - return sz; -} - - -template <typename Tree> -void -EnumStoreBase::fixupRefCounts(const EnumVector &hist, Tree &tree) -{ - if ( hist.empty() ) - return; - typename Tree::Iterator ti(tree.begin()); - typedef EnumVector::const_iterator HistIT; - - for (HistIT hi(hist.begin()), hie(hist.end()); hi != hie; ++hi, ++ti) { - assert(ti.valid()); - fixupRefCount(ti.getKey(), *hi); - } - assert(!ti.valid()); - freeUnusedEnums(false); -} - - -vespalib::asciistream & operator << (vespalib::asciistream & os, const EnumStoreBase::Index & idx) { - return os << "offset(" << idx.offset() << "), bufferId(" << idx.bufferId() << "), idx(" << idx.ref() << ")"; -} - - -template class datastore::DataStoreT<EnumStoreIndex>; - -template -ssize_t -EnumStoreBase::deserialize<EnumTree>(const void *src, size_t available, IndexVector &idx, EnumTree &tree); - -template -ssize_t -EnumStoreBase::deserialize<EnumPostingTree>(const void *src, size_t available, IndexVector &idx, EnumPostingTree &tree); - -template -void -EnumStoreBase::fixupRefCounts<EnumTree>(const EnumVector &hist, EnumTree &tree); - -template -void -EnumStoreBase::fixupRefCounts<EnumPostingTree>(const EnumVector &hist, EnumPostingTree &tree); - -} - -namespace vespalib { -template class RcuVectorBase<search::EnumStoreIndex>; -} - -VESPALIB_HASH_MAP_INSTANTIATE_H_E_M(search::EnumStoreIndex, search::EnumStoreIndex, - vespalib::hash<search::EnumStoreIndex>, std::equal_to<search::EnumStoreIndex>, - vespalib::hashtable_base::and_modulator); diff --git a/searchlib/src/vespa/searchlib/attribute/enumstorebase.h b/searchlib/src/vespa/searchlib/attribute/enumstorebase.h deleted file mode 100644 index 32e7e5134ca..00000000000 --- a/searchlib/src/vespa/searchlib/attribute/enumstorebase.h +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "enum_store_dictionary.h" -#include <vespa/searchcommon/attribute/iattributevector.h> -#include <vespa/vespalib/datastore/datastore.h> -#include <vespa/vespalib/datastore/entryref.h> -#include <vespa/vespalib/stllike/hash_map.h> -#include <vespa/vespalib/util/address_space.h> -#include <vespa/vespalib/util/array.h> -#include <vespa/vespalib/util/memoryusage.h> -#include <atomic> -#include <set> - -namespace vespalib { class asciistream; } -namespace search { - -class BufferWriter; - -namespace attribute { class Status; } - -using EnumStoreComparator = datastore::EntryComparator; - - -class EnumStoreBase -{ -public: - using DataStoreType = datastore::DataStoreT<EnumStoreIndex>; - using EnumHandle = attribute::IAttributeVector::EnumHandle; - using EnumVector = EnumStoreEnumVector; - using Index = EnumStoreIndex; - using IndexVector = EnumStoreIndexVector; - using generation_t = vespalib::GenerationHandler::generation_t; - - using EnumIndexMap = vespalib::hash_map<Index, Index, vespalib::hash<Index>, std::equal_to<Index>, - vespalib::hashtable_base::and_modulator>; - - class EntryBase { - protected: - char * _data; - public: - EntryBase(void * data) : _data(static_cast<char *>(data)) {} - - uint32_t getRefCount() const { - return *(reinterpret_cast<uint32_t *>(_data) + 1); - } - - void incRefCount() { - uint32_t *dst = reinterpret_cast<uint32_t *>(_data) + 1; - ++(*dst); - } - - void decRefCount() { - uint32_t *dst = reinterpret_cast<uint32_t *>(_data) + 1; - --(*dst); - } - - void setRefCount(uint32_t refCount) { - uint32_t *dst = reinterpret_cast<uint32_t *>(_data) + 1; - *dst = refCount; - } - - static uint32_t size() { return 2*sizeof(uint32_t); } - }; - - using IndexSet = std::set<Index, CompareEnumIndex>; - -protected: - - class EnumBufferType : public datastore::BufferType<char> { - private: - size_t _minSizeNeeded; // lower cap for sizeNeeded - size_t _deadElems; // dead elements in active buffer - bool _pendingCompact; - bool _wantCompact; - public: - EnumBufferType(); - - size_t calcArraysToAlloc(uint32_t bufferId, size_t sizeNeeded, bool resizing) const override; - - void setSizeNeededAndDead(size_t sizeNeeded, size_t deadElems) { - _minSizeNeeded = sizeNeeded; - _deadElems = deadElems; - } - - void onFree(size_t usedElems) override { - datastore::BufferType<char>::onFree(usedElems); - _pendingCompact = _wantCompact; - _wantCompact = false; - } - - void setWantCompact() { _wantCompact = true; } - bool getPendingCompact() const { return _pendingCompact; } - void clearPendingCompact() { _pendingCompact = false; } - }; - - IEnumStoreDictionary *_enumDict; - DataStoreType _store; - EnumBufferType _type; - std::vector<uint32_t> _toHoldBuffers; // used during compaction - - static const uint32_t TYPE_ID = 0; - - EnumStoreBase(uint64_t initBufferSize, bool hasPostings); - - virtual ~EnumStoreBase(); - - EntryBase getEntryBase(Index idx) const { - return EntryBase(const_cast<DataStoreType &>(_store).getEntry<char>(idx)); - } - datastore::BufferState & getBuffer(uint32_t bufferIdx) { - return _store.getBufferState(bufferIdx); - } - const datastore::BufferState & getBuffer(uint32_t bufferIdx) const { - return _store.getBufferState(bufferIdx); - } - bool validIndex(Index idx) const { - return (idx.valid() && idx.offset() < _store.getBufferState(idx.bufferId()).size()); - } - - uint32_t getBufferIndex(datastore::BufferState::State status); - void postCompact(); - bool preCompact(uint64_t bytesNeeded); - -public: - void reset(uint64_t initBufferSize); - - uint32_t getRefCount(Index idx) const { return getEntryBase(idx).getRefCount(); } - void incRefCount(Index idx) { getEntryBase(idx).incRefCount(); } - void decRefCount(Index idx) { getEntryBase(idx).decRefCount(); } - - // Only use when reading from enumerated attribute save files - void fixupRefCount(Index idx, uint32_t refCount) { - getEntryBase(idx).setRefCount(refCount); - } - - template <typename Tree> - void fixupRefCounts(const EnumVector &hist, Tree &tree); - - uint32_t getNumUniques() const { return _enumDict->getNumUniques(); } - - uint32_t getRemaining() const { - return _store.getBufferState(_store.getActiveBufferId(TYPE_ID)).remaining(); - } - uint32_t getCapacity() const { - return _store.getBufferState(_store.getActiveBufferId(TYPE_ID)).capacity(); - } - vespalib::MemoryUsage getMemoryUsage() const; - vespalib::MemoryUsage getTreeMemoryUsage() const { return _enumDict->get_memory_usage(); } - - vespalib::AddressSpace getAddressSpaceUsage() const; - - void transferHoldLists(generation_t generation); - void trimHoldLists(generation_t firstUsed); - - static void failNewSize(uint64_t minNewSize, uint64_t maxSize); - - // Align buffers and entries to 4 bytes boundary. - static uint64_t alignBufferSize(uint64_t val) { return Index::align(val); } - static uint32_t alignEntrySize(uint32_t val) { return Index::align(val); } - - void fallbackResize(uint64_t bytesNeeded); - bool getPendingCompact() const { return _type.getPendingCompact(); } - void clearPendingCompact() { _type.clearPendingCompact(); } - - virtual void writeValues(BufferWriter &writer, const Index *idxs, size_t count) const = 0; - - virtual ssize_t deserialize(const void *src, size_t available, size_t &initSpace) = 0; - virtual ssize_t deserialize(const void *src, size_t available, Index &idx) = 0; - virtual bool foldedChange(const Index &idx1, const Index &idx2) = 0; - - ssize_t deserialize0(const void *src, size_t available, IndexVector &idx); - - template <typename Tree> - ssize_t deserialize(const void *src, size_t available, IndexVector &idx, Tree &tree); - - ssize_t deserialize(const void *src, size_t available, IndexVector &idx) { - return _enumDict->deserialize(src, available, idx); - } - - virtual void freeUnusedEnum(Index idx, IndexSet &unused) = 0; - virtual void freeUnusedEnums(bool movePostingIdx) = 0; - virtual void freeUnusedEnums(const IndexSet& toRemove) = 0; - - void fixupRefCounts(const EnumVector &hist) { _enumDict->fixupRefCounts(hist); } - void freezeTree() { _enumDict->freeze(); } - - virtual bool performCompaction(uint64_t bytesNeeded, EnumIndexMap & old2New) = 0; - - IEnumStoreDictionary &getEnumStoreDict() { return *_enumDict; } - const IEnumStoreDictionary &getEnumStoreDict() const { return *_enumDict; } - EnumPostingTree &getPostingDictionary() { return _enumDict->getPostingDictionary(); } - - const EnumPostingTree &getPostingDictionary() const { - return _enumDict->getPostingDictionary(); - } - const datastore::DataStoreBase &get_data_store_base() const { return _store; } -}; - -vespalib::asciistream & operator << (vespalib::asciistream & os, const EnumStoreBase::Index & idx); - -extern template -class datastore::DataStoreT<EnumStoreIndex>; - - -} diff --git a/searchlib/src/vespa/searchlib/attribute/floatbase.hpp b/searchlib/src/vespa/searchlib/attribute/floatbase.hpp index a454fd3e235..3925bb3dd4e 100644 --- a/searchlib/src/vespa/searchlib/attribute/floatbase.hpp +++ b/searchlib/src/vespa/searchlib/attribute/floatbase.hpp @@ -48,7 +48,7 @@ FloatingPointAttributeTemplate<T>::findEnum(const char *value, EnumHandle &e) co } template<typename T> -std::vector<EnumStoreBase::EnumHandle> +std::vector<IEnumStore::EnumHandle> FloatingPointAttributeTemplate<T>::findFoldedEnums(const char *value) const { std::vector<EnumHandle> result; diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h new file mode 100644 index 00000000000..0963e0ff67d --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h @@ -0,0 +1,93 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/searchcommon/attribute/iattributevector.h> +#include <vespa/vespalib/datastore/entryref.h> +#include <vespa/vespalib/stllike/hash_map.h> +#include <vespa/vespalib/util/array.h> +#include <vespa/vespalib/util/memoryusage.h> +#include <cassert> +#include <set> + +namespace search { + +namespace datastore { class DataStoreBase; } + +class BufferWriter; +class IEnumStoreDictionary; + +/** + * Interface for an enum store that is independent of the data type stored. + */ +class IEnumStore { +public: + using Index = datastore::AlignedEntryRefT<31, 4>; + using IndexVector = vespalib::Array<Index>; + using EnumHandle = attribute::IAttributeVector::EnumHandle; + using EnumVector = vespalib::Array<uint32_t>; + + using EnumIndexMap = vespalib::hash_map<Index, Index, vespalib::hash<Index>, std::equal_to<Index>, + vespalib::hashtable_base::and_modulator>; + + struct CompareEnumIndex { + using Index = IEnumStore::Index; + + bool operator()(const Index &lhs, const Index &rhs) const { + return lhs.ref() < rhs.ref(); + } + }; + + using IndexSet = std::set<Index, CompareEnumIndex>; + + virtual ~IEnumStore() = default; + + virtual void writeValues(BufferWriter& writer, const Index* idxs, size_t count) const = 0; + virtual ssize_t deserialize0(const void* src, size_t available, IndexVector& idx) = 0; + virtual void fixupRefCount(Index idx, uint32_t refCount) = 0; + virtual void freeUnusedEnum(Index idx, IndexSet& unused) = 0; + virtual void freeUnusedEnums(bool movePostingIdx) = 0; + virtual bool foldedChange(const Index& idx1, const Index& idx2) = 0; + virtual IEnumStoreDictionary& getEnumStoreDict() = 0; + virtual const IEnumStoreDictionary& getEnumStoreDict() const = 0; + virtual const datastore::DataStoreBase& get_data_store_base() const = 0; + virtual uint32_t getNumUniques() const = 0; + virtual vespalib::MemoryUsage getMemoryUsage() const = 0; + virtual vespalib::MemoryUsage getTreeMemoryUsage() const = 0; + + + template <typename TreeT> + ssize_t deserialize(const void *src, + size_t available, + IndexVector& idx, + TreeT& tree) { + ssize_t sz(deserialize0(src, available, idx)); + if (sz >= 0) { + typename TreeT::Builder builder(tree.getAllocator()); + typedef IndexVector::const_iterator IT; + for (IT i(idx.begin()), ie(idx.end()); i != ie; ++i) { + builder.insert(*i, typename TreeT::DataType()); + } + tree.assign(builder); + } + return sz; + } + + template <typename TreeT> + void fixupRefCounts(const EnumVector& hist, TreeT& tree) { + if (hist.empty()) { + return; + } + typename TreeT::Iterator ti(tree.begin()); + typedef EnumVector::const_iterator HistIT; + + for (HistIT hi(hist.begin()), hie(hist.end()); hi != hie; ++hi, ++ti) { + assert(ti.valid()); + fixupRefCount(ti.getKey(), *hi); + } + assert(!ti.valid()); + freeUnusedEnums(false); + } +}; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h index 3c324a30779..a4c14256835 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h +++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h @@ -2,48 +2,36 @@ #pragma once +#include "i_enum_store.h" #include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/vespalib/datastore/entry_comparator_wrapper.h> #include <vespa/vespalib/datastore/unique_store_dictionary.h> -#include <set> namespace search { class BufferWriter; -using EnumStoreIndex = datastore::AlignedEntryRefT<31, 4>; -using EnumStoreIndexVector = vespalib::Array<EnumStoreIndex>; -using EnumStoreEnumVector = vespalib::Array<uint32_t>; - using EnumTreeTraits = btree::BTreeTraits<16, 16, 10, true>; -using EnumTree = btree::BTree<EnumStoreIndex, btree::BTreeNoLeafData, +using EnumTree = btree::BTree<IEnumStore::Index, btree::BTreeNoLeafData, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; -using EnumPostingTree = btree::BTree<EnumStoreIndex, datastore::EntryRef, +using EnumPostingTree = btree::BTree<IEnumStore::Index, datastore::EntryRef, btree::NoAggregated, const datastore::EntryComparatorWrapper, EnumTreeTraits>; -struct CompareEnumIndex { - using Index = EnumStoreIndex; - - bool operator()(const Index &lhs, const Index &rhs) const { - return lhs.ref() < rhs.ref(); - } -}; - /** * Interface for the dictionary used by an enum store. */ class IEnumStoreDictionary : public datastore::IUniqueStoreDictionary { public: - using EnumVector = EnumStoreEnumVector; - using Index = EnumStoreIndex; - using IndexSet = std::set<Index, CompareEnumIndex>; - using IndexVector = EnumStoreIndexVector; + using EnumVector = IEnumStore::EnumVector; + using Index = IEnumStore::Index; + using IndexSet = IEnumStore::IndexSet; + using IndexVector = IEnumStore::IndexVector; using generation_t = vespalib::GenerationHandler::generation_t; public: diff --git a/searchlib/src/vespa/searchlib/attribute/integerbase.hpp b/searchlib/src/vespa/searchlib/attribute/integerbase.hpp index 7b23cd51e92..a08ce394a46 100644 --- a/searchlib/src/vespa/searchlib/attribute/integerbase.hpp +++ b/searchlib/src/vespa/searchlib/attribute/integerbase.hpp @@ -34,7 +34,7 @@ IntegerAttributeTemplate<T>::findEnum(const char *value, EnumHandle &e) const { template<typename T> -std::vector<EnumStoreBase::EnumHandle> +std::vector<IEnumStore::EnumHandle> IntegerAttributeTemplate<T>::findFoldedEnums(const char *value) const { std::vector<EnumHandle> result; diff --git a/searchlib/src/vespa/searchlib/attribute/load_utils.cpp b/searchlib/src/vespa/searchlib/attribute/load_utils.cpp index 96df7d06b39..041daa08cd5 100644 --- a/searchlib/src/vespa/searchlib/attribute/load_utils.cpp +++ b/searchlib/src/vespa/searchlib/attribute/load_utils.cpp @@ -1,10 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include "i_enum_store.h" #include "load_utils.hpp" -#include "multivalue.h" -#include "enumstorebase.h" #include "loadedenumvalue.h" #include "multi_value_mapping.h" +#include "multivalue.h" #include <vespa/vespalib/util/array.hpp> using search::multivalue::Value; @@ -26,7 +26,7 @@ INSTANTIATE_ARRAY(ValueType, Saver); \ INSTANTIATE_WSET(ValueType, Saver) #define INSTANTIATE_ENUM(Saver) \ -INSTANTIATE_SINGLE_ARRAY_WSET(EnumStoreIndex, Saver) +INSTANTIATE_SINGLE_ARRAY_WSET(IEnumStore::Index, Saver) #define INSTANTIATE_VALUE(ValueType) \ INSTANTIATE_SINGLE_ARRAY_WSET(ValueType, NoSaveLoadedEnum) diff --git a/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h b/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h index 49cadf379db..4fa3510fbec 100644 --- a/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h +++ b/searchlib/src/vespa/searchlib/attribute/loadedenumvalue.h @@ -3,7 +3,8 @@ #pragma once #include <vespa/vespalib/util/array.h> -#include <vespa/searchlib/attribute/enumstorebase.h> +#include <vespa/vespalib/util/arrayref.h> +#include <vespa/searchlib/attribute/i_enum_store.h> namespace search { @@ -125,7 +126,7 @@ class SaveEnumHist vespalib::ArrayRef<uint32_t> _hist; public: - SaveEnumHist(EnumStoreBase::EnumVector &enumHist) + SaveEnumHist(IEnumStore::EnumVector &enumHist) : _hist(enumHist) { } diff --git a/searchlib/src/vespa/searchlib/attribute/loadedstringvalue.cpp b/searchlib/src/vespa/searchlib/attribute/loadedstringvalue.cpp deleted file mode 100644 index 83515d5d331..00000000000 --- a/searchlib/src/vespa/searchlib/attribute/loadedstringvalue.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "loadedstringvalue.h" - -using vespalib::Array; -using vespalib::alloc::Alloc; - -namespace search { -namespace attribute { - -void -sortLoadedByValue(LoadedStringVectorReal &loaded) -{ - Array<unsigned> radixScratchPad(loaded.size(), Alloc::allocMMap()); - for(size_t i(0), m(loaded.size()); i < m; i++) { - loaded[i].prepareRadixSort(); - } - radix_sort(LoadedStringValue::ValueRadix(), - LoadedStringValue::ValueCompare(), - AlwaysEof<LoadedStringValue>(), - 1, - &loaded[0], - loaded.size(), - &radixScratchPad[0], - 0, - 96); -} - -void -sortLoadedByDocId(LoadedStringVectorReal &loaded) -{ - ShiftBasedRadixSorter<LoadedStringValue, - LoadedStringValue::DocRadix, - LoadedStringValue::DocOrderCompare, 56>:: - radix_sort(LoadedStringValue::DocRadix(), - LoadedStringValue::DocOrderCompare(), - &loaded[0], - loaded.size(), - 16); -} - - -} // namespace attribute -} // namespace search - diff --git a/searchlib/src/vespa/searchlib/attribute/loadedstringvalue.h b/searchlib/src/vespa/searchlib/attribute/loadedstringvalue.h deleted file mode 100644 index 6b4a93176f7..00000000000 --- a/searchlib/src/vespa/searchlib/attribute/loadedstringvalue.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <vespa/searchlib/common/sort.h> -#include <vespa/searchlib/util/fileutil.h> -#include <vespa/searchlib/util/foldedstringcompare.h> -#include <vespa/vespalib/text/utf8.h> -#include <vespa/vespalib/text/lowercase.h> -#include "loadedvalue.h" - -namespace search -{ - -namespace attribute -{ - -/** - * Temporary representation of enumerated attribute loaded from non-enumerated - * save file (i.e. old save format). For string data types. - */ - -template <typename B> -struct RadixSortable : public B -{ - RadixSortable() - : B(), - _currRadix(NULL), - _currRadixFolding(false) - { - } - - class ValueRadix - { - public: - uint32_t - operator ()(RadixSortable &x) const - { - vespalib::Utf8ReaderForZTS u8reader(x._currRadix); - uint32_t val = u8reader.getChar(); - if (x._currRadixFolding) { - if (val != 0) { - val = vespalib::LowerCase::convert(val); - } else { - // switch to returning unfolded values - x._currRadix = x.getValue(); - x._currRadixFolding = false; - val = 1; - } - } - return val; - } - }; - - class ValueCompare : public std::binary_function<B, B, bool> - { - FoldedStringCompare _compareHelper; - public: - bool - operator()(const B &x, const B &y) const - { - return _compareHelper.compare(x.getValue(), y.getValue()) < 0; - } - }; - - void - prepareRadixSort() - { - _currRadix = this->getValue(); - _currRadixFolding = true; - } -private: - const char * _currRadix; - bool _currRadixFolding; -}; - -typedef RadixSortable<LoadedValue<const char *> > LoadedStringValue; - -typedef SequentialReadModifyWriteInterface<LoadedStringValue> LoadedStringVector; - -typedef SequentialReadModifyWriteVector<LoadedStringValue> -LoadedStringVectorReal; - - -void -sortLoadedByValue(LoadedStringVectorReal &loaded); - -void -sortLoadedByDocId(LoadedStringVectorReal &loaded); - - -} // namespace attribute - -} // namespace search - diff --git a/searchlib/src/vespa/searchlib/attribute/loadedvalue.h b/searchlib/src/vespa/searchlib/attribute/loadedvalue.h index 38baed6b3ea..b1d1c178e5f 100644 --- a/searchlib/src/vespa/searchlib/attribute/loadedvalue.h +++ b/searchlib/src/vespa/searchlib/attribute/loadedvalue.h @@ -3,7 +3,7 @@ #pragma once #include <vespa/searchcommon/common/undefinedvalues.h> -#include <vespa/searchlib/attribute/enumstorebase.h> +#include <vespa/searchlib/attribute/i_enum_store.h> #include <vespa/vespalib/datastore/entryref.h> namespace search @@ -57,14 +57,14 @@ public: } }; - EnumStoreBase::Index + IEnumStore::Index getEidx() const { - return EnumStoreBase::Index(datastore::EntryRef(_value._eidx)); + return IEnumStore::Index(datastore::EntryRef(_value._eidx)); } void - setEidx(EnumStoreBase::Index v) + setEidx(IEnumStore::Index v) { _value._eidx = v.ref(); } diff --git a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.cpp b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.cpp index ab047c41e2d..6a1a5194890 100644 --- a/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.cpp +++ b/searchlib/src/vespa/searchlib/attribute/multi_value_mapping.cpp @@ -1,10 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include "attributevector.h" +#include "i_enum_store.h" #include "multi_value_mapping.h" #include "multi_value_mapping.hpp" #include "multivalue.h" -#include "enumstorebase.h" -#include "attributevector.h" #include <vespa/vespalib/util/array.hpp> using search::multivalue::Value; @@ -13,8 +13,8 @@ using search::multivalue::WeightedValue; namespace search { namespace attribute { -template class MultiValueMapping<Value<EnumStoreIndex>>; -template class MultiValueMapping<WeightedValue<EnumStoreIndex>>; +template class MultiValueMapping<Value<IEnumStore::Index>>; +template class MultiValueMapping<WeightedValue<IEnumStore::Index>>; template class MultiValueMapping<Value<int8_t>>; template class MultiValueMapping<WeightedValue<int8_t>>; template class MultiValueMapping<Value<int16_t>>; diff --git a/searchlib/src/vespa/searchlib/attribute/multienumattribute.h b/searchlib/src/vespa/searchlib/attribute/multienumattribute.h index c0f8e3515d3..ac271247e70 100644 --- a/searchlib/src/vespa/searchlib/attribute/multienumattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multienumattribute.h @@ -2,17 +2,18 @@ #pragma once -#include "multivalueattribute.h" -#include "enumstorebase.h" +#include "i_enum_store.h" #include "loadedenumvalue.h" #include "multivalue.h" +#include "multivalueattribute.h" +#include "no_loaded_vector.h" namespace search { class IWeightedIndexVector { public: virtual ~IWeightedIndexVector() = default; - using WeightedIndex = multivalue::WeightedValue<EnumStoreBase::Index>; + using WeightedIndex = multivalue::WeightedValue<IEnumStore::Index>; /** * Provides a reference to the underlying enum/weight pairs. * This method should only be invoked if @ref getCollectionType(docId) returns CollectionType::WEIGHTED_SET. @@ -49,11 +50,11 @@ protected: using generation_t = typename B::BaseClass::generation_t; using DocIndices = typename MultiValueAttribute<B, M>::DocumentValues; - using EnumIndex = typename EnumStoreBase::Index; - using EnumIndexMap = EnumStoreBase::EnumIndexMap; - using EnumIndexVector = typename EnumStoreBase::IndexVector; + using EnumIndex = IEnumStore::Index; + using EnumIndexMap = IEnumStore::EnumIndexMap; + using EnumIndexVector = IEnumStore::IndexVector; using EnumStoreBatchUpdater = typename B::EnumStoreBatchUpdater; - using EnumVector = typename EnumStoreBase::EnumVector; + using EnumVector = IEnumStore::EnumVector; using LoadedEnumAttribute = attribute::LoadedEnumAttribute; using LoadedEnumAttributeVector = attribute::LoadedEnumAttributeVector; using WeightedIndex = typename MultiValueAttribute<B, M>::MultiValueType; diff --git a/searchlib/src/vespa/searchlib/attribute/multienumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multienumattribute.hpp index 3447ab6d168..5352dc492fd 100644 --- a/searchlib/src/vespa/searchlib/attribute/multienumattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multienumattribute.hpp @@ -84,20 +84,22 @@ template <typename B, typename M> void MultiValueEnumAttribute<B, M>::fillValues(LoadedVector & loaded) { - uint32_t numDocs(this->getNumDocs()); - size_t numValues = loaded.size(); - size_t count = 0; - WeightedIndexVector indices; - this->_mvMapping.prepareLoadFromMultiValue(); - for (DocId doc = 0; doc < numDocs; ++doc) { - for(const auto* v = & loaded.read();(count < numValues) && (v->_docId == doc); count++, loaded.next(), v = & loaded.read()) { - indices.push_back(WeightedIndex(v->getEidx(), v->getWeight())); + if constexpr(!std::is_same_v<LoadedVector, NoLoadedVector>) { + uint32_t numDocs(this->getNumDocs()); + size_t numValues = loaded.size(); + size_t count = 0; + WeightedIndexVector indices; + this->_mvMapping.prepareLoadFromMultiValue(); + for (DocId doc = 0; doc < numDocs; ++doc) { + for(const auto* v = & loaded.read();(count < numValues) && (v->_docId == doc); count++, loaded.next(), v = & loaded.read()) { + indices.push_back(WeightedIndex(v->getEidx(), v->getWeight())); + } + this->checkSetMaxValueCount(indices.size()); + this->_mvMapping.set(doc, indices); + indices.clear(); } - this->checkSetMaxValueCount(indices.size()); - this->_mvMapping.set(doc, indices); - indices.clear(); + this->_mvMapping.doneLoadFromMultiValue(); } - this->_mvMapping.doneLoadFromMultiValue(); } diff --git a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp index 32f46d859bc..13079b6591c 100644 --- a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp @@ -21,7 +21,7 @@ namespace { */ class DatWriter { - std::vector<EnumStoreIndex> _indexes; + std::vector<IEnumStore::Index> _indexes; const EnumAttributeSaver::Enumerator &_enumerator; std::unique_ptr<search::BufferWriter> _datWriter; std::function<bool()> _compaction_interferred; @@ -80,7 +80,7 @@ MultiValueEnumAttributeSaver<MultiValueT>:: MultiValueEnumAttributeSaver(GenerationHandler::Guard &&guard, const attribute::AttributeHeader &header, const MultiValueMapping &mvMapping, - const EnumStoreBase &enumStore) + const IEnumStore &enumStore) : Parent(std::move(guard), header, mvMapping), _mvMapping(mvMapping), _enumSaver(enumStore), @@ -134,8 +134,8 @@ onSave(IAttributeSaveTarget &saveTarget) return !compaction_broke_save; } -using EnumIdxArray = multivalue::Value<EnumStoreIndex>; -using EnumIdxWset = multivalue::WeightedValue<EnumStoreIndex>; +using EnumIdxArray = multivalue::Value<IEnumStore::Index>; +using EnumIdxWset = multivalue::WeightedValue<IEnumStore::Index>; template class MultiValueEnumAttributeSaver<EnumIdxArray>; template class MultiValueEnumAttributeSaver<EnumIdxWset>; diff --git a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h index d5d0db7acdc..3f770c2a0bb 100644 --- a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h +++ b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h @@ -7,7 +7,7 @@ namespace search { -/* +/** * Class for saving an enumerated multivalue attribute. * * Template argument MultiValueT is either multivalue::Value<ValueType> or @@ -33,7 +33,7 @@ public: MultiValueEnumAttributeSaver(GenerationHandler::Guard &&guard, const attribute::AttributeHeader &header, const MultiValueMapping &mvMapping, - const EnumStoreBase &enumStore); + const IEnumStore &enumStore); ~MultiValueEnumAttributeSaver() override; }; diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h index 498a1e398f9..75453268120 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.h @@ -24,9 +24,9 @@ public: protected: using DocId = typename B::BaseClass::DocId; using EnumHandle = typename B::BaseClass::EnumHandle; - using EnumIndex = EnumStoreBase::Index; - using EnumIndexVector = EnumStoreBase::IndexVector; - using EnumVector = EnumStoreBase::EnumVector; + using EnumIndex = IEnumStore::Index; + using EnumIndexVector = IEnumStore::IndexVector; + using EnumVector = IEnumStore::EnumVector; using LoadedEnumAttribute = attribute::LoadedEnumAttribute; using LoadedEnumAttributeVector = attribute::LoadedEnumAttributeVector; using LoadedNumericValueT = typename B::BaseClass::LoadedNumericValueT; diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h index e990a1030f5..32e98ef7d6d 100644 --- a/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multinumericpostattribute.h @@ -14,8 +14,8 @@ namespace search { * This class is used for both array and weighted set types. * * B: EnumAttribute<P, BaseClass> - * M: multivalue::Value<EnumStoreBase::Index> (array) or - * multivalue::WeightedValue<EnumStoreBase::Index> (weighted set) + * M: multivalue::Value<IEnumStore::Index> (array) or + * multivalue::WeightedValue<IEnumStore::Index> (weighted set) * M specifies the type stored in the MultiValueMapping */ template <typename B, typename M> diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.cpp b/searchlib/src/vespa/searchlib/attribute/multistringattribute.cpp index 6c0d9342f39..5c08d1f6184 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.cpp @@ -6,8 +6,8 @@ namespace search { -template class MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::Value<EnumStoreBase::Index> >; -template class MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::WeightedValue<EnumStoreBase::Index> >; +template class MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::Value<IEnumStore::Index> >; +template class MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::WeightedValue<IEnumStore::Index> >; } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.h b/searchlib/src/vespa/searchlib/attribute/multistringattribute.h index ef5158c162a..c117aeea6b9 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.h @@ -19,8 +19,8 @@ namespace search { * This class is used for both array and weighted set types. * * B: Base class: EnumAttribute<StringAttribute> - * M: multivalue::Value<EnumStoreBase::Index> (array) or - * multivalue::WeightedValue<EnumStoreBase::Index> (weighted set) + * M: multivalue::Value<IEnumStore::Index> (array) or + * multivalue::WeightedValue<IEnumStore::Index> (weighted set) */ template <typename B, typename M> class MultiValueStringAttributeT : public MultiValueEnumAttribute<B, M> { @@ -169,7 +169,7 @@ public: }; -using ArrayStringAttribute = MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::Value<EnumStoreBase::Index> >; -using WeightedSetStringAttribute = MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::WeightedValue<EnumStoreBase::Index> >; +using ArrayStringAttribute = MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::Value<IEnumStore::Index> >; +using WeightedSetStringAttribute = MultiValueStringAttributeT<EnumAttribute<StringAttribute>, multivalue::WeightedValue<IEnumStore::Index> >; } diff --git a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.cpp b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.cpp index 75e05d61b13..4409bdd5857 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.cpp @@ -8,8 +8,8 @@ LOG_SETUP(".searchlib.attribute.multi_string_post_attribute"); namespace search { -EnumStoreBase::Index -StringEnumIndexMapper::map(EnumStoreBase::Index original, const EnumStoreComparator & compare) const +IEnumStore::Index +StringEnumIndexMapper::map(IEnumStore::Index original, const datastore::EntryComparator& compare) const { return _dictionary.find(original, compare).getKey(); } diff --git a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h index 88df7ec9704..c98e6db4fde 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.h @@ -14,8 +14,8 @@ namespace search { * This class is used for both array and weighted set types. * * B: EnumAttribute<StringAttribute> - * T: multivalue::Value<EnumStoreBase::Index> (array) or - * multivalue::WeightedValue<EnumStoreBase::Index> (weighted set) + * T: multivalue::Value<IEnumStore::Index> (array) or + * multivalue::WeightedValue<IEnumStore::Index> (weighted set) */ template <typename B, typename T> class MultiValueStringPostingAttributeT @@ -112,8 +112,8 @@ public: } }; -using ArrayStringPostingAttribute = MultiValueStringPostingAttributeT<EnumAttribute<StringAttribute>, multivalue::Value<EnumStoreBase::Index> >; -using WeightedSetStringPostingAttribute = MultiValueStringPostingAttributeT<EnumAttribute<StringAttribute>, multivalue::WeightedValue<EnumStoreBase::Index> >; +using ArrayStringPostingAttribute = MultiValueStringPostingAttributeT<EnumAttribute<StringAttribute>, multivalue::Value<IEnumStore::Index> >; +using WeightedSetStringPostingAttribute = MultiValueStringPostingAttributeT<EnumAttribute<StringAttribute>, multivalue::WeightedValue<IEnumStore::Index> >; } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp index 8268d1ace20..154bbb91809 100644 --- a/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/multistringpostattribute.hpp @@ -30,7 +30,7 @@ class StringEnumIndexMapper : public EnumIndexMapper { public: StringEnumIndexMapper(const EnumPostingTree & dictionary) : _dictionary(dictionary) { } - EnumStoreBase::Index map(EnumStoreBase::Index original, const EnumStoreComparator & compare) const override; + IEnumStore::Index map(IEnumStore::Index original, const datastore::EntryComparator& compare) const override; virtual bool hasFold() const override { return true; } private: const EnumPostingTree & _dictionary; diff --git a/searchlib/src/vespa/searchlib/attribute/no_loaded_vector.h b/searchlib/src/vespa/searchlib/attribute/no_loaded_vector.h new file mode 100644 index 00000000000..a3be87181bb --- /dev/null +++ b/searchlib/src/vespa/searchlib/attribute/no_loaded_vector.h @@ -0,0 +1,15 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +namespace search { + +/* + * Tag class, used to stub out code for loading enumerated attributes + * from non-enumerated files for data types where enumeration is + * mandatory. + */ +class NoLoadedVector { +}; + +} diff --git a/searchlib/src/vespa/searchlib/attribute/numericbase.h b/searchlib/src/vespa/searchlib/attribute/numericbase.h index 08a61620071..687dd0face6 100644 --- a/searchlib/src/vespa/searchlib/attribute/numericbase.h +++ b/searchlib/src/vespa/searchlib/attribute/numericbase.h @@ -3,7 +3,7 @@ #pragma once #include "attributevector.h" -#include "enumstorebase.h" +#include "i_enum_store.h" #include "loadedenumvalue.h" #include <vespa/searchlib/common/sort.h> @@ -14,9 +14,9 @@ class ReaderBase; class NumericAttribute : public AttributeVector { protected: - typedef EnumStoreBase::Index EnumIndex; - typedef EnumStoreBase::IndexVector EnumIndexVector; - typedef EnumStoreBase::EnumVector EnumVector; + typedef IEnumStore::Index EnumIndex; + typedef IEnumStore::IndexVector EnumIndexVector; + typedef IEnumStore::EnumVector EnumVector; NumericAttribute(const vespalib::string & name, const AttributeVector::Config & cfg) : AttributeVector(name, cfg) diff --git a/searchlib/src/vespa/searchlib/attribute/postingchange.cpp b/searchlib/src/vespa/searchlib/attribute/postingchange.cpp index 1eb1fc8c3ee..a98c030bcee 100644 --- a/searchlib/src/vespa/searchlib/attribute/postingchange.cpp +++ b/searchlib/src/vespa/searchlib/attribute/postingchange.cpp @@ -101,8 +101,8 @@ removeDupRemovals(std::vector<uint32_t> &removals) } -EnumStoreBase::Index -EnumIndexMapper::map(EnumStoreBase::Index original, const EnumStoreComparator & compare) const +IEnumStore::Index +EnumIndexMapper::map(IEnumStore::Index original, const datastore::EntryComparator& compare) const { (void) compare; return original; @@ -163,21 +163,21 @@ PostingChange<P>::apply(GrowableBitVector &bv) template <typename WeightedIndex> class ActualChangeComputer { public: - using EnumIndex = EnumStoreBase::Index; + using EnumIndex = IEnumStore::Index; using AlwaysWeightedIndexVector = std::vector<multivalue::WeightedValue<EnumIndex>>; using WeightedIndexVector = std::vector<WeightedIndex>; void compute(const WeightedIndex * entriesNew, size_t szNew, const WeightedIndex * entriesOld, size_t szOld, AlwaysWeightedIndexVector & added, AlwaysWeightedIndexVector & changed, AlwaysWeightedIndexVector & removed); - ActualChangeComputer(const EnumStoreComparator &compare, const EnumIndexMapper &mapper); + ActualChangeComputer(const datastore::EntryComparator& compare, const EnumIndexMapper& mapper); ~ActualChangeComputer(); private: WeightedIndexVector _oldEntries; WeightedIndexVector _newEntries; vespalib::hash_map<uint32_t, uint32_t> _cachedMapping; - const EnumStoreComparator &_compare; + const datastore::EntryComparator &_compare; const EnumIndexMapper &_mapper; const bool _hasFold; @@ -219,7 +219,7 @@ private: template <typename WeightedIndex> class MergeDupIterator { using InnerIter = typename std::vector<WeightedIndex>::const_iterator; - using EnumIndex = EnumStoreBase::Index; + using EnumIndex = IEnumStore::Index; using Entry = multivalue::WeightedValue<EnumIndex>; InnerIter _cur; InnerIter _end; @@ -262,7 +262,7 @@ public: }; template <typename WeightedIndex> -ActualChangeComputer<WeightedIndex>::ActualChangeComputer(const EnumStoreComparator &compare, +ActualChangeComputer<WeightedIndex>::ActualChangeComputer(const datastore::EntryComparator &compare, const EnumIndexMapper &mapper) : _oldEntries(), _newEntries(), @@ -318,7 +318,7 @@ template <typename MultivalueMapping> PostingMap PostingChangeComputerT<WeightedIndex, PostingMap>:: compute(const MultivalueMapping & mvm, const DocIndices & docIndices, - const EnumStoreComparator & compare, const EnumIndexMapper & mapper) + const datastore::EntryComparator & compare, const EnumIndexMapper & mapper) { typedef ActualChangeComputer<WeightedIndex> AC; AC actualChange(compare, mapper); @@ -350,7 +350,7 @@ template class PostingChange<AttributeWeightPosting>; typedef PostingChange<btree::BTreeKeyData<unsigned int, int> > WeightedPostingChange; typedef std::map<EnumPostingPair, WeightedPostingChange> WeightedPostingChangeMap; -typedef EnumStoreBase::Index EnumIndex; +typedef IEnumStore::Index EnumIndex; typedef multivalue::WeightedValue<EnumIndex> WeightedIndex; typedef multivalue::Value<EnumIndex> ValueIndex; @@ -362,13 +362,13 @@ typedef std::vector<std::pair<uint32_t, std::vector<ValueIndex>>> DocIndicesValu template WeightedPostingChangeMap PostingChangeComputerT<WeightedIndex, WeightedPostingChangeMap> ::compute<WeightedMultiValueMapping>(const WeightedMultiValueMapping &, const DocIndicesWeighted &, - const EnumStoreComparator &, + const datastore::EntryComparator &, const EnumIndexMapper &); template WeightedPostingChangeMap PostingChangeComputerT<ValueIndex, WeightedPostingChangeMap> ::compute<ValueMultiValueMapping>(const ValueMultiValueMapping &, const DocIndicesValue &, - const EnumStoreComparator &, + const datastore::EntryComparator &, const EnumIndexMapper &); } diff --git a/searchlib/src/vespa/searchlib/attribute/postingchange.h b/searchlib/src/vespa/searchlib/attribute/postingchange.h index 00904954a2b..569fbfd6517 100644 --- a/searchlib/src/vespa/searchlib/attribute/postingchange.h +++ b/searchlib/src/vespa/searchlib/attribute/postingchange.h @@ -2,12 +2,14 @@ #pragma once +#include "i_enum_store.h" #include "postingdata.h" -#include "enumstorebase.h" #include <vespa/vespalib/util/array.h> namespace search { +namespace datastore { class EntryComparator; } + class GrowableBitVector; /** @@ -48,7 +50,7 @@ class EnumIndexMapper { public: virtual ~EnumIndexMapper() { } - virtual EnumStoreBase::Index map(EnumStoreBase::Index original, const EnumStoreComparator & compare) const; + virtual IEnumStore::Index map(IEnumStore::Index original, const datastore::EntryComparator& compare) const; virtual bool hasFold() const { return false; } }; @@ -60,7 +62,7 @@ private: public: template <typename MultivalueMapping> static PostingMap compute(const MultivalueMapping & mvm, const DocIndices & docIndices, - const EnumStoreComparator & compare, const EnumIndexMapper & mapper); + const datastore::EntryComparator & compare, const EnumIndexMapper & mapper); }; template <> diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp b/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp index aa515e82c94..c8ee6ab50b2 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp @@ -12,12 +12,12 @@ using attribute::LoadedNumericValue; template <typename P> PostingListAttributeBase<P>:: PostingListAttributeBase(AttributeVector &attr, - EnumStoreBase &enumStore) + IEnumStore &enumStore) : attribute::IPostingListAttributeBase(), - _postingList(enumStore.getPostingDictionary(), attr.getStatus(), + _postingList(enumStore.getEnumStoreDict().getPostingDictionary(), attr.getStatus(), attr.getConfig()), _attr(attr), - _dict(enumStore.getPostingDictionary()), + _dict(enumStore.getEnumStoreDict().getPostingDictionary()), _esb(enumStore) { } @@ -53,7 +53,7 @@ PostingListAttributeBase<P>::fillPostingsFixupEnumBase(const LoadedEnumAttribute { clearAllPostings(); uint32_t docIdLimit = _attr.getNumDocs(); - EnumStoreBase &enumStore = _esb; + IEnumStore &enumStore = _esb; EntryRef newIndex; PostingChange<P> postings; if (loaded.empty()) { @@ -114,7 +114,7 @@ PostingListAttributeBase<P>::fillPostingsFixupEnumBase(const LoadedEnumAttribute template <typename P> void PostingListAttributeBase<P>::updatePostings(PostingMap &changePost, - EnumStoreComparator &cmp) + datastore::EntryComparator &cmp) { for (auto& elem : changePost) { auto& change = elem.second; @@ -159,7 +159,7 @@ PostingListAttributeBase<P>:: clearPostings(attribute::IAttributeVector::EnumHandle eidx, uint32_t fromLid, uint32_t toLid, - EnumStoreComparator &cmp) + datastore::EntryComparator &cmp) { PostingChange<P> postings; @@ -220,61 +220,61 @@ void PostingListAttributeSubBase<P, LoadedVector, LoadedValueType, EnumStoreType>:: handleFillPostings(LoadedVector &loaded) { - clearAllPostings(); - EntryRef newIndex; - PostingChange<P> postings; - uint32_t docIdLimit = _attr.getNumDocs(); - _postingList.resizeBitVectors(docIdLimit, docIdLimit); - if ( ! loaded.empty() ) { - vespalib::Array<typename LoadedVector::Type> similarValues; - auto value = loaded.read(); - LoadedValueType prev = value.getValue(); - for (size_t i(0), m(loaded.size()); i < m; i++, loaded.next()) { - value = loaded.read(); - if (FoldedComparatorType::compareFolded(prev, value.getValue()) == 0) { - // for single value attributes loaded[numDocs] is used - // for default value but we don't want to add an - // invalid docId to the posting list. - if (value._docId < docIdLimit) { - postings.add(value._docId, value.getWeight()); + if constexpr (!std::is_same_v<LoadedVector, NoLoadedVector>) { + clearAllPostings(); + EntryRef newIndex; + PostingChange<P> postings; + uint32_t docIdLimit = _attr.getNumDocs(); + _postingList.resizeBitVectors(docIdLimit, docIdLimit); + if ( ! loaded.empty() ) { + vespalib::Array<typename LoadedVector::Type> similarValues; + auto value = loaded.read(); + LoadedValueType prev = value.getValue(); + for (size_t i(0), m(loaded.size()); i < m; i++, loaded.next()) { + value = loaded.read(); + if (FoldedComparatorType::compareFolded(prev, value.getValue()) == 0) { + // for single value attributes loaded[numDocs] is used + // for default value but we don't want to add an + // invalid docId to the posting list. + if (value._docId < docIdLimit) { + postings.add(value._docId, value.getWeight()); + similarValues.push_back(value); + } + } else { + postings.removeDups(); + newIndex = EntryRef(); + _postingList.apply(newIndex, + &postings._additions[0], + &postings._additions[0] + + postings._additions.size(), + &postings._removals[0], + &postings._removals[0] + + postings._removals.size()); + postings.clear(); + if (value._docId < docIdLimit) { + postings.add(value._docId, value.getWeight()); + } + similarValues[0]._pidx = newIndex; + for (size_t j(0), k(similarValues.size()); j < k; j++) { + loaded.write(similarValues[j]); + } + similarValues.clear(); similarValues.push_back(value); + prev = value.getValue(); } - } else { - postings.removeDups(); - - newIndex = EntryRef(); - _postingList.apply(newIndex, - &postings._additions[0], - &postings._additions[0] + - postings._additions.size(), - &postings._removals[0], - &postings._removals[0] + - postings._removals.size()); - postings.clear(); - if (value._docId < docIdLimit) { - postings.add(value._docId, value.getWeight()); - } - similarValues[0]._pidx = newIndex; - for (size_t j(0), k(similarValues.size()); j < k; j++) { - loaded.write(similarValues[j]); - } - similarValues.clear(); - similarValues.push_back(value); - prev = value.getValue(); } - } - - postings.removeDups(); - newIndex = EntryRef(); - _postingList.apply(newIndex, - &postings._additions[0], - &postings._additions[0] + - postings._additions.size(), - &postings._removals[0], - &postings._removals[0] + postings._removals.size()); - similarValues[0]._pidx = newIndex; - for (size_t i(0), m(similarValues.size()); i < m; i++) { - loaded.write(similarValues[i]); + postings.removeDups(); + newIndex = EntryRef(); + _postingList.apply(newIndex, + &postings._additions[0], + &postings._additions[0] + + postings._additions.size(), + &postings._removals[0], + &postings._removals[0] + postings._removals.size()); + similarValues[0]._pidx = newIndex; + for (size_t i(0), m(similarValues.size()); i < m; i++) { + loaded.write(similarValues[i]); + } } } } @@ -359,7 +359,7 @@ PostingListAttributeSubBase<AttributePosting, template class PostingListAttributeSubBase<AttributePosting, - attribute::LoadedStringVector, + NoLoadedVector, const char *, EnumStoreT<StringEntryType > >; @@ -401,7 +401,7 @@ PostingListAttributeSubBase<AttributeWeightPosting, template class PostingListAttributeSubBase<AttributeWeightPosting, - attribute::LoadedStringVector, + NoLoadedVector, const char *, EnumStoreT<StringEntryType > >; diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistattribute.h b/searchlib/src/vespa/searchlib/attribute/postinglistattribute.h index b9346daefa2..69b6cf73fa8 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/postinglistattribute.h @@ -13,22 +13,23 @@ #include <vespa/vespalib/btree/btreestore.h> #include <vespa/vespalib/datastore/entry_comparator.h> #include <vespa/vespalib/datastore/entryref.h> +#include <map> namespace search { class EnumPostingPair { private: - EnumStoreBase::Index _idx; + IEnumStore::Index _idx; const datastore::EntryComparator *_cmp; public: - EnumPostingPair(EnumStoreBase::Index idx, const datastore::EntryComparator *cmp) + EnumPostingPair(IEnumStore::Index idx, const datastore::EntryComparator *cmp) : _idx(idx), _cmp(cmp) { } bool operator<(const EnumPostingPair &rhs) const { return (*_cmp)(_idx, rhs._idx); } - EnumStoreBase::Index getEnumIdx() const { return _idx; } + IEnumStore::Index getEnumIdx() const { return _idx; } }; @@ -41,7 +42,7 @@ protected: using AggregationTraits = attribute::PostingListTraits<DataType>; using DocId = AttributeVector::DocId; using EntryRef = datastore::EntryRef; - using EnumIndex = EnumStoreBase::Index; + using EnumIndex = IEnumStore::Index; using LoadedEnumAttributeVector = attribute::LoadedEnumAttributeVector; using PostingList = typename AggregationTraits::PostingList; using PostingMap = std::map<EnumPostingPair, PostingChange<P> >; @@ -49,14 +50,14 @@ protected: PostingList _postingList; AttributeVector &_attr; EnumPostingTree &_dict; - EnumStoreBase &_esb; + IEnumStore &_esb; - PostingListAttributeBase(AttributeVector &attr, EnumStoreBase &enumStore); + PostingListAttributeBase(AttributeVector &attr, IEnumStore &enumStore); virtual ~PostingListAttributeBase(); virtual void updatePostings(PostingMap & changePost) = 0; - void updatePostings(PostingMap &changePost, EnumStoreComparator &cmp); + void updatePostings(PostingMap &changePost, datastore::EntryComparator &cmp); void clearAllPostings(); void disableFreeLists() { _postingList.disableFreeLists(); } void disableElemHoldList() { _postingList.disableElemHoldList(); } @@ -64,7 +65,7 @@ protected: bool forwardedOnAddDoc(DocId doc, size_t wantSize, size_t wantCapacity); void clearPostings(attribute::IAttributeVector::EnumHandle eidx, uint32_t fromLid, - uint32_t toLid, EnumStoreComparator &cmp); + uint32_t toLid, datastore::EntryComparator &cmp); void forwardedShrinkLidSpace(uint32_t newSize) override; virtual vespalib::MemoryUsage getMemoryUsage() const override; @@ -82,7 +83,7 @@ public: using Dictionary = EnumPostingTree; using EntryRef = datastore::EntryRef; - using EnumIndex = EnumStoreBase::Index; + using EnumIndex = IEnumStore::Index; using EnumStore = EnumStoreType; using FoldedComparatorType = typename EnumStore::FoldedComparatorType; using LoadedEnumAttributeVector = attribute::LoadedEnumAttributeVector; diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp index 3c3242ce47c..70cf5f00edb 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.cpp @@ -15,7 +15,7 @@ PostingListSearchContext(const Dictionary &dictionary, uint32_t docIdLimit, uint64_t numValues, bool hasWeight, - const EnumStoreBase &esb, + const IEnumStore &esb, uint32_t minBvDocFreq, bool useBitVector, const ISearchContext &baseSearchCtx) @@ -44,7 +44,7 @@ PostingListSearchContext::~PostingListSearchContext() = default; void -PostingListSearchContext::lookupTerm(const EnumStoreComparator &comp) +PostingListSearchContext::lookupTerm(const datastore::EntryComparator &comp) { _lowerDictItr.lower_bound(_frozenDictionary.getRoot(), EnumIndex(), comp); _upperDictItr = _lowerDictItr; @@ -56,8 +56,8 @@ PostingListSearchContext::lookupTerm(const EnumStoreComparator &comp) void -PostingListSearchContext::lookupRange(const EnumStoreComparator &low, - const EnumStoreComparator &high) +PostingListSearchContext::lookupRange(const datastore::EntryComparator &low, + const datastore::EntryComparator &high) { _lowerDictItr.lower_bound(_frozenDictionary.getRoot(), EnumIndex(), low); _upperDictItr = _lowerDictItr; diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h index 6a2324cef07..a274528c92b 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.h @@ -26,7 +26,7 @@ protected: using Dictionary = EnumPostingTree; using DictionaryConstIterator = Dictionary::ConstIterator; using FrozenDictionary = Dictionary::FrozenView; - using EnumIndex = EnumStoreBase::Index; + using EnumIndex = IEnumStore::Index; const FrozenDictionary _frozenDictionary; DictionaryConstIterator _lowerDictItr; @@ -41,19 +41,19 @@ protected: datastore::EntryRef _frozenRoot; // Posting list in tree form float _FSTC; // Filtering Search Time Constant float _PLSTC; // Posting List Search Time Constant - const EnumStoreBase &_esb; + const IEnumStore &_esb; uint32_t _minBvDocFreq; const GrowableBitVector *_gbv; // bitvector if _useBitVector has been set const ISearchContext &_baseSearchCtx; PostingListSearchContext(const Dictionary &dictionary, uint32_t docIdLimit, uint64_t numValues, bool hasWeight, - const EnumStoreBase &esb, uint32_t minBvDocFreq, bool useBitVector, const ISearchContext &baseSearchCtx); + const IEnumStore &esb, uint32_t minBvDocFreq, bool useBitVector, const ISearchContext &baseSearchCtx); ~PostingListSearchContext(); - void lookupTerm(const EnumStoreComparator &comp); - void lookupRange(const EnumStoreComparator &low, const EnumStoreComparator &high); + void lookupTerm(const datastore::EntryComparator &comp); + void lookupRange(const datastore::EntryComparator &low, const datastore::EntryComparator &high); void lookupSingle(); virtual bool useThis(const DictionaryConstIterator & it) const { (void) it; @@ -113,7 +113,7 @@ protected: static const long MIN_APPROXHITS_TO_NUMDOCS_RATIO_BEFORE_APPROXIMATION = 10; PostingListSearchContextT(const Dictionary &dictionary, uint32_t docIdLimit, uint64_t numValues, - bool hasWeight, const PostingList &postingList, const EnumStoreBase &esb, + bool hasWeight, const PostingList &postingList, const IEnumStore &esb, uint32_t minBvCocFreq, bool useBitVector, const ISearchContext &baseSearchCtx); ~PostingListSearchContextT(); @@ -151,7 +151,7 @@ protected: using Parent::singleHits; PostingListFoldedSearchContextT(const Dictionary &dictionary, uint32_t docIdLimit, uint64_t numValues, - bool hasWeight, const PostingList &postingList, const EnumStoreBase &esb, + bool hasWeight, const PostingList &postingList, const IEnumStore &esb, uint32_t minBvCocFreq, bool useBitVector, const ISearchContext &baseSearchCtx); unsigned int approximateHits() const override; diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp index 15ff9c1ea7a..e2ac4069172 100644 --- a/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp +++ b/searchlib/src/vespa/searchlib/attribute/postinglistsearchcontext.hpp @@ -20,7 +20,7 @@ namespace search::attribute { template <typename DataT> PostingListSearchContextT<DataT>:: PostingListSearchContextT(const Dictionary &dictionary, uint32_t docIdLimit, uint64_t numValues, bool hasWeight, - const PostingList &postingList, const EnumStoreBase &esb, + const PostingList &postingList, const IEnumStore &esb, uint32_t minBvDocFreq, bool useBitVector, const ISearchContext &searchContext) : PostingListSearchContext(dictionary, docIdLimit, numValues, hasWeight, esb, minBvDocFreq, useBitVector, searchContext), _postingList(postingList), @@ -286,7 +286,7 @@ PostingListSearchContextT<DataT>::applyRangeLimit(int rangeLimit) template <typename DataT> PostingListFoldedSearchContextT<DataT>:: PostingListFoldedSearchContextT(const Dictionary &dictionary, uint32_t docIdLimit, uint64_t numValues, - bool hasWeight, const PostingList &postingList, const EnumStoreBase &esb, + bool hasWeight, const PostingList &postingList, const IEnumStore &esb, uint32_t minBvDocFreq, bool useBitVector, const ISearchContext &searchContext) : Parent(dictionary, docIdLimit, numValues, hasWeight, postingList, esb, minBvDocFreq, useBitVector, searchContext) { diff --git a/searchlib/src/vespa/searchlib/attribute/postingstore.h b/searchlib/src/vespa/searchlib/attribute/postingstore.h index 7ca1fa5e641..278b587deda 100644 --- a/searchlib/src/vespa/searchlib/attribute/postingstore.h +++ b/searchlib/src/vespa/searchlib/attribute/postingstore.h @@ -2,8 +2,8 @@ #pragma once +#include "enum_store_dictionary.h" #include "postinglisttraits.h" -#include "enumstorebase.h" #include <set> namespace search { diff --git a/searchlib/src/vespa/searchlib/attribute/singleenumattribute.cpp b/searchlib/src/vespa/searchlib/attribute/singleenumattribute.cpp index 0e122c9d583..9e5c9f0bc7b 100644 --- a/searchlib/src/vespa/searchlib/attribute/singleenumattribute.cpp +++ b/searchlib/src/vespa/searchlib/attribute/singleenumattribute.cpp @@ -29,7 +29,7 @@ AttributeVector::DocId SingleValueEnumAttributeBase::addDoc(bool &incGeneration) { incGeneration = _enumIndices.isFull(); - _enumIndices.push_back(EnumStoreBase::Index()); + _enumIndices.push_back(IEnumStore::Index()); return _enumIndices.size() - 1; } diff --git a/searchlib/src/vespa/searchlib/attribute/singleenumattribute.h b/searchlib/src/vespa/searchlib/attribute/singleenumattribute.h index 0edb12325d2..5624ebe6582 100644 --- a/searchlib/src/vespa/searchlib/attribute/singleenumattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/singleenumattribute.h @@ -19,14 +19,14 @@ class SingleValueEnumAttributeBase { protected: using DocId = AttributeVector::DocId; using EnumHandle = AttributeVector::EnumHandle; - using EnumIndex = EnumStoreBase::Index; + using EnumIndex = IEnumStore::Index; using EnumIndexVector = vespalib::RcuVectorBase<EnumIndex>; using GenerationHolder = vespalib::GenerationHolder; public: using EnumIndexCopyVector = vespalib::Array<EnumIndex>; - EnumStoreBase::Index getEnumIndex(DocId docId) const { return _enumIndices[docId]; } + IEnumStore::Index getEnumIndex(DocId docId) const { return _enumIndices[docId]; } EnumHandle getE(DocId doc) const { return _enumIndices[doc].ref(); } protected: SingleValueEnumAttributeBase(const attribute::Config & c, GenerationHolder &genHolder); @@ -45,7 +45,7 @@ protected: using ChangeVector = typename B::ChangeVector; using ChangeVectorIterator = typename B::ChangeVector::const_iterator; using DocId = typename B::DocId; - using EnumIndexMap = EnumStoreBase::EnumIndexMap; + using EnumIndexMap = IEnumStore::EnumIndexMap; using EnumModifier = typename B::EnumModifier; using EnumStore = typename B::EnumStore; using EnumStoreBatchUpdater = typename EnumStore::BatchUpdater; @@ -87,12 +87,12 @@ protected: void fillValues(LoadedVector & loaded) override; void fillEnumIdx(ReaderBase &attrReader, - const EnumStoreBase::IndexVector &eidxs, + const IEnumStore::IndexVector &eidxs, LoadedEnumAttributeVector &loaded) override; void fillEnumIdx(ReaderBase &attrReader, - const EnumStoreBase::IndexVector &eidxs, - EnumStoreBase::EnumVector &enumHist) override; + const IEnumStore::IndexVector &eidxs, + IEnumStore::EnumVector &enumHist) override; /** * Called when a new document has been added. diff --git a/searchlib/src/vespa/searchlib/attribute/singleenumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singleenumattribute.hpp index fcee2c8635f..08095b6bf13 100644 --- a/searchlib/src/vespa/searchlib/attribute/singleenumattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singleenumattribute.hpp @@ -204,12 +204,14 @@ template <typename B> void SingleValueEnumAttribute<B>::fillValues(LoadedVector & loaded) { - uint32_t numDocs = this->getNumDocs(); - getGenerationHolder().clearHoldLists(); - _enumIndices.reset(); - _enumIndices.unsafe_reserve(numDocs); - for (DocId doc = 0; doc < numDocs; ++doc, loaded.next()) { - _enumIndices.push_back(loaded.read().getEidx()); + if constexpr (!std::is_same_v<LoadedVector, NoLoadedVector>) { + uint32_t numDocs = this->getNumDocs(); + getGenerationHolder().clearHoldLists(); + _enumIndices.reset(); + _enumIndices.unsafe_reserve(numDocs); + for (DocId doc = 0; doc < numDocs; ++doc, loaded.next()) { + _enumIndices.push_back(loaded.read().getEidx()); + } } } @@ -217,7 +219,7 @@ SingleValueEnumAttribute<B>::fillValues(LoadedVector & loaded) template <typename B> void SingleValueEnumAttribute<B>::fillEnumIdx(ReaderBase &attrReader, - const EnumStoreBase::IndexVector &eidxs, + const IEnumStore::IndexVector &eidxs, LoadedEnumAttributeVector &loaded) { attribute::loadFromEnumeratedSingleValue(_enumIndices, @@ -231,8 +233,8 @@ SingleValueEnumAttribute<B>::fillEnumIdx(ReaderBase &attrReader, template <typename B> void SingleValueEnumAttribute<B>::fillEnumIdx(ReaderBase &attrReader, - const EnumStoreBase::IndexVector &eidxs, - EnumStoreBase::EnumVector &enumHist) + const IEnumStore::IndexVector &eidxs, + IEnumStore::EnumVector &enumHist) { attribute::loadFromEnumeratedSingleValue(_enumIndices, getGenerationHolder(), diff --git a/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.cpp b/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.cpp index 31569cc9535..afa893458b4 100644 --- a/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.cpp @@ -14,7 +14,7 @@ SingleValueEnumAttributeSaver:: SingleValueEnumAttributeSaver(GenerationHandler::Guard &&guard, const attribute::AttributeHeader &header, EnumIndexCopyVector &&indices, - const EnumStoreBase &enumStore) + const IEnumStore &enumStore) : AttributeSaver(std::move(guard), header), _indices(std::move(indices)), _enumSaver(enumStore) diff --git a/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.h b/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.h index 5a58e75a203..29210a8f31d 100644 --- a/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.h +++ b/searchlib/src/vespa/searchlib/attribute/singleenumattributesaver.h @@ -24,7 +24,7 @@ public: SingleValueEnumAttributeSaver(vespalib::GenerationHandler::Guard &&guard, const attribute::AttributeHeader &header, EnumIndexCopyVector &&indices, - const EnumStoreBase &enumStore); + const IEnumStore &enumStore); virtual ~SingleValueEnumAttributeSaver(); }; diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h index 49f907a66a7..dcf71ff9132 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.h @@ -22,10 +22,10 @@ protected: using DocId = typename B::BaseClass::DocId; using EnumHandle = typename B::BaseClass::EnumHandle; using EnumIndex = typename SingleValueEnumAttributeBase::EnumIndex; - using EnumIndexVector = EnumStoreBase::IndexVector; + using EnumIndexVector = IEnumStore::IndexVector; using EnumStore = typename SingleValueEnumAttribute<B>::EnumStore; using EnumStoreBatchUpdater = typename EnumStore::BatchUpdater; - using EnumVector = EnumStoreBase::EnumVector; + using EnumVector = IEnumStore::EnumVector; using LoadedEnumAttribute = attribute::LoadedEnumAttribute; using LoadedEnumAttributeVector = attribute::LoadedEnumAttributeVector; using LoadedNumericValueT = typename B::BaseClass::LoadedNumericValueT; diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.h b/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.h index 4895eb2256a..23ec0016abf 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.h @@ -63,7 +63,7 @@ private: void mergeMemoryStats(vespalib::MemoryUsage & total) override; void applyUpdateValueChange(const Change & c, EnumStore & enumStore, std::map<DocId, EnumIndex> & currEnumIndices); - void makePostingChange(const EnumStoreComparator *cmp, + void makePostingChange(const datastore::EntryComparator *cmp, const std::map<DocId, EnumIndex> &currEnumIndices, PostingMap &changePost); diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp index 0b80c7cbf4a..8afb0418b68 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlenumericpostattribute.hpp @@ -53,7 +53,7 @@ SingleValueNumericPostingAttribute<B>::applyUpdateValueChange(const Change & c, template <typename B> void SingleValueNumericPostingAttribute<B>:: -makePostingChange(const EnumStoreComparator *cmpa, +makePostingChange(const datastore::EntryComparator *cmpa, const std::map<DocId, EnumIndex> &currEnumIndices, PostingMap &changePost) { diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.h b/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.h index 5afbc5aee1b..49d1be93580 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.h +++ b/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.h @@ -72,7 +72,7 @@ private: std::map<DocId, EnumIndex> &currEnumIndices); void - makePostingChange(const EnumStoreComparator *cmp, + makePostingChange(const datastore::EntryComparator *cmp, Dictionary &dict, const std::map<DocId, EnumIndex> &currEnumIndices, PostingMap &changePost); diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp index 8374647311e..ed76a8eca14 100644 --- a/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/singlestringpostattribute.hpp @@ -51,7 +51,7 @@ SingleValueStringPostingAttributeT<B>::applyUpdateValueChange(const Change & c, template <typename B> void SingleValueStringPostingAttributeT<B>:: -makePostingChange(const EnumStoreComparator *cmpa, +makePostingChange(const datastore::EntryComparator *cmpa, Dictionary &dict, const std::map<DocId, EnumIndex> &currEnumIndices, PostingMap &changePost) diff --git a/searchlib/src/vespa/searchlib/attribute/stringbase.h b/searchlib/src/vespa/searchlib/attribute/stringbase.h index 9839cfe6004..39f40e0fffe 100644 --- a/searchlib/src/vespa/searchlib/attribute/stringbase.h +++ b/searchlib/src/vespa/searchlib/attribute/stringbase.h @@ -2,15 +2,15 @@ #pragma once +#include "no_loaded_vector.h" #include <vespa/searchlib/attribute/attributevector.h> +#include <vespa/searchlib/attribute/changevector.h> +#include <vespa/searchlib/attribute/i_enum_store.h> +#include <vespa/searchlib/attribute/loadedenumvalue.h> #include <vespa/searchlib/util/foldedstringcompare.h> +#include <vespa/vespalib/text/lowercase.h> #include <vespa/vespalib/text/utf8.h> #include <vespa/vespalib/util/regexp.h> -#include <vespa/vespalib/text/lowercase.h> -#include <vespa/searchlib/attribute/enumstorebase.h> -#include <vespa/searchlib/attribute/loadedenumvalue.h> -#include <vespa/searchlib/attribute/loadedstringvalue.h> -#include <vespa/searchlib/attribute/changevector.h> namespace search { @@ -22,10 +22,10 @@ class StringAttribute : public AttributeVector public: typedef vespalib::Array<uint32_t> OffsetVector; typedef const char * LoadedValueType; - typedef EnumStoreBase::Index EnumIndex; - typedef EnumStoreBase::IndexVector EnumIndexVector; - typedef EnumStoreBase::EnumVector EnumVector; - typedef attribute::LoadedStringVector LoadedVector; + typedef IEnumStore::Index EnumIndex; + typedef IEnumStore::IndexVector EnumIndexVector; + typedef IEnumStore::EnumVector EnumVector; + using LoadedVector = NoLoadedVector; public: DECLARE_IDENTIFIABLE_ABSTRACT(StringAttribute); bool append(DocId doc, const vespalib::string & v, int32_t weight) { @@ -73,7 +73,6 @@ protected: virtual vespalib::MemoryUsage getChangeVectorMemoryUsage() const override; private: - typedef attribute::LoadedStringVectorReal LoadedVectorR; virtual void fillPostings(LoadedVector & loaded); virtual void fillEnum(LoadedVector & loaded); virtual void fillValues(LoadedVector & loaded); diff --git a/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.cpp b/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.cpp index b372834f3f8..23a0d2d52a6 100644 --- a/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/sourceblendersearch.cpp @@ -2,6 +2,7 @@ #include "sourceblendersearch.h" #include "isourceselector.h" +#include <vespa/fastos/dynamiclibrary.h> #include <vespa/vespalib/objects/visit.hpp> #include <vespa/vespalib/util/array.hpp> diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java index 13150158dad..7116bf72ec4 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java @@ -67,10 +67,9 @@ public class DefaultZtsClient extends ClientBase implements ZtsClient { public InstanceIdentity registerInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String attestationData, - String hostname, Pkcs10Csr csr) { InstanceRegisterInformation payload = - new InstanceRegisterInformation(providerIdentity, instanceIdentity, attestationData, hostname, csr); + new InstanceRegisterInformation(providerIdentity, instanceIdentity, attestationData, csr); HttpUriRequest request = RequestBuilder.post() .setUri(ztsUrl.resolve("instance/")) .setEntity(toJsonStringEntity(payload)) @@ -82,9 +81,8 @@ public class DefaultZtsClient extends ClientBase implements ZtsClient { public InstanceIdentity refreshInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String instanceId, - String hostname, Pkcs10Csr csr) { - InstanceRefreshInformation payload = new InstanceRefreshInformation(csr, hostname); + InstanceRefreshInformation payload = new InstanceRefreshInformation(csr); URI uri = ztsUrl.resolve( String.format("instance/%s/%s/%s/%s", providerIdentity.getFullName(), diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java index 4f44dba4864..c09ad8f48a0 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java @@ -29,7 +29,6 @@ public interface ZtsClient extends AutoCloseable { */ InstanceIdentity registerInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, - String hostname, String attestationData, Pkcs10Csr csr); @@ -41,7 +40,6 @@ public interface ZtsClient extends AutoCloseable { InstanceIdentity refreshInstance(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String instanceId, - String hostname, Pkcs10Csr csr); /** diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRefreshInformation.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRefreshInformation.java index 5d101ed31e6..f6c359c09a8 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRefreshInformation.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRefreshInformation.java @@ -18,11 +18,8 @@ public class InstanceRefreshInformation { @JsonProperty("csr") @JsonSerialize(using = Pkcs10CsrSerializer.class) private final Pkcs10Csr csr; - @JsonProperty("hostname") - private final String hostname; - public InstanceRefreshInformation(Pkcs10Csr csr, String hostname) { + public InstanceRefreshInformation(Pkcs10Csr csr) { this.csr = csr; - this.hostname = hostname; } } diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRegisterInformation.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRegisterInformation.java index c5175f19b44..cd272ccf685 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRegisterInformation.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/InstanceRegisterInformation.java @@ -25,21 +25,17 @@ public class InstanceRegisterInformation { private final String service; @JsonProperty("attestationData") private final String attestationData; - @JsonProperty("hostname") - private final String hostname; @JsonProperty("csr") private final String csr; public InstanceRegisterInformation(AthenzIdentity providerIdentity, AthenzIdentity instanceIdentity, String attestationData, - String hostname, Pkcs10Csr csr) { this.provider = providerIdentity.getFullName(); this.domain = instanceIdentity.getDomain().getName(); this.service = instanceIdentity.getName(); this.attestationData = attestationData; this.csr = Pkcs10CsrUtils.toPem(csr); - this.hostname = hostname; } } diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java index 8e0bdb9b19c..eccf1088cce 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java @@ -75,7 +75,6 @@ class AthenzCredentialsService { Pkcs10Csr csr = csrGenerator.generateInstanceCsr( tenantIdentity, document.providerUniqueId(), - /*hostname*/null, // no hostname in tenant certificates document.ipAddresses(), keyPair); @@ -84,7 +83,6 @@ class AthenzCredentialsService { ztsClient.registerInstance( configserverIdentity, tenantIdentity, - /*hostname*/null, EntityBindingsMapper.toAttestationData(document), csr); X509Certificate certificate = instanceIdentity.certificate(); @@ -98,7 +96,6 @@ class AthenzCredentialsService { Pkcs10Csr csr = csrGenerator.generateInstanceCsr( tenantIdentity, document.providerUniqueId(), - /*hostname*/null, // no hostname in tenant certificates document.ipAddresses(), newKeyPair); @@ -107,7 +104,6 @@ class AthenzCredentialsService { ztsClient.refreshInstance( configserverIdentity, tenantIdentity, - /*hostname*/null, document.providerUniqueId().asDottedString(), csr); X509Certificate certificate = instanceIdentity.certificate(); diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java index dff753b9126..f73a52b373b 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java @@ -34,13 +34,11 @@ public class CsrGenerator { public Pkcs10Csr generateInstanceCsr(AthenzIdentity instanceIdentity, VespaUniqueInstanceId instanceId, - String hostname, Set<String> ipAddresses, KeyPair keyPair) { X500Principal subject = new X500Principal(String.format("OU=%s, CN=%s", providerService, instanceIdentity.getFullName())); // Add SAN dnsname <service>.<domain-with-dashes>.<provider-dnsname-suffix> // and SAN dnsname <provider-unique-instance-id>.instanceid.athenz.<provider-dnsname-suffix> - // and SAN dnsname <hostname> (note: ZTS will verify that there is a DNS A record with hostname having the remote ip) Pkcs10CsrBuilder pkcs10CsrBuilder = Pkcs10CsrBuilder.fromKeypair(subject, keyPair, SHA256_WITH_RSA) .addSubjectAlternativeName( DNS_NAME, @@ -50,9 +48,6 @@ public class CsrGenerator { instanceIdentity.getDomainName().replace(".", "-"), dnsSuffix)) .addSubjectAlternativeName(DNS_NAME, getIdentitySAN(instanceId)); - if (hostname != null) { - pkcs10CsrBuilder.addSubjectAlternativeName(DNS_NAME, hostname); - } ipAddresses.forEach(ip -> pkcs10CsrBuilder.addSubjectAlternativeName(new SubjectAlternativeName(IP_ADDRESS, ip))); return pkcs10CsrBuilder.build(); } diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java index 3b2129821a3..8b6d2f06777 100644 --- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java +++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java @@ -31,7 +31,7 @@ public class InstanceCsrGeneratorTest { VespaUniqueInstanceId vespaUniqueInstanceId = VespaUniqueInstanceId.fromDottedString("0.default.default.foo-app.vespa.us-north-1.prod.node"); KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA); - Pkcs10Csr csr = csrGenerator.generateInstanceCsr(service, vespaUniqueInstanceId, "myhostname", Collections.emptySet(), keyPair); + Pkcs10Csr csr = csrGenerator.generateInstanceCsr(service, vespaUniqueInstanceId, Collections.emptySet(), keyPair); assertEquals(new X500Principal(String.format("OU=%s, CN=%s", PROVIDER_SERVICE, ATHENZ_SERVICE)), csr.getSubject()); } } diff --git a/vespa-documentgen-plugin/etc/music/music.sd b/vespa-documentgen-plugin/etc/music/music.sd index b5083d4e490..5295b1bf449 100644 --- a/vespa-documentgen-plugin/etc/music/music.sd +++ b/vespa-documentgen-plugin/etc/music/music.sd @@ -24,6 +24,10 @@ search music { indexing: summary | attribute } + field eitheror type bool { + indexing: summary | attribute + } + field url type uri { indexing: summary | index } diff --git a/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java b/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java index 3afd84725bf..ae40ad6154a 100644 --- a/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java +++ b/vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java @@ -894,6 +894,7 @@ public class DocumentGenMojo extends AbstractMojo { if (DataType.DOCUMENT.equals(dt)) return "com.yahoo.document.Document"; if (DataType.URI.equals(dt)) return "java.net.URI"; if (DataType.BYTE.equals(dt)) return "java.lang.Byte"; + if (DataType.BOOL.equals(dt)) return "java.lang.Boolean"; if (DataType.TAG.equals(dt)) return "java.lang.String"; if (dt instanceof StructDataType) return className(dt.getName()); if (dt instanceof WeightedSetDataType) return "java.util.Map<"+toJavaType(((WeightedSetDataType)dt).getNestedType())+",java.lang.Integer>"; @@ -921,6 +922,7 @@ public class DocumentGenMojo extends AbstractMojo { if (DataType.DOCUMENT.equals(dt)) return "com.yahoo.document.DataType.DOCUMENT"; if (DataType.URI.equals(dt)) return "com.yahoo.document.DataType.URI"; if (DataType.BYTE.equals(dt)) return "com.yahoo.document.DataType.BYTE"; + if (DataType.BOOL.equals(dt)) return "com.yahoo.document.DataType.BOOL"; if (DataType.TAG.equals(dt)) return "com.yahoo.document.DataType.TAG"; if (dt instanceof StructDataType) return "new com.yahoo.document.StructDataType(\""+dt.getName()+"\")"; if (dt instanceof WeightedSetDataType) return "new com.yahoo.document.WeightedSetDataType("+toJavaReference(((WeightedSetDataType)dt).getNestedType())+", "+ diff --git a/vespa-documentgen-plugin/src/test/java/com/yahoo/vespa/DocumentGenTest.java b/vespa-documentgen-plugin/src/test/java/com/yahoo/vespa/DocumentGenTest.java index c195e116bf0..a65701fe261 100644 --- a/vespa-documentgen-plugin/src/test/java/com/yahoo/vespa/DocumentGenTest.java +++ b/vespa-documentgen-plugin/src/test/java/com/yahoo/vespa/DocumentGenTest.java @@ -5,6 +5,7 @@ import com.yahoo.document.DataType; import com.yahoo.document.StructDataType; import com.yahoo.document.WeightedSetDataType; import com.yahoo.searchdefinition.Search; +import org.junit.Ignore; import org.junit.Test; import java.io.File; @@ -23,6 +24,7 @@ public class DocumentGenTest { Map<String, Search> searches = mojo.getSearches(); assertEquals(searches.size(),1); assertEquals(searches.get("music").getDocument("music").getField("title").getDataType(), DataType.STRING); + assertEquals(searches.get("music").getDocument("music").getField("eitheror").getDataType(), DataType.BOOL); } @Test diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp index 8867a40228a..729177d394c 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.hpp @@ -3,6 +3,8 @@ #pragma once #include "unique_store_enumerator.h" +#include <vespa/vespalib/datastore/bufferstate.h> +#include <vespa/vespalib/datastore/datastorebase.h> namespace search::datastore { |