diff options
116 files changed, 622 insertions, 994 deletions
diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index 5f86db1d385..3d5b9e8d59e 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -538,6 +538,7 @@ ], "methods" : [ "public void <init>(int)", + "public void <init>()", "public void render(java.io.OutputStream)" ], "fields" : [ ] diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/EmptyResponse.java b/container-core/src/main/java/com/yahoo/container/jdisc/EmptyResponse.java index 4477b7319b8..4d207d7afaf 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/EmptyResponse.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/EmptyResponse.java @@ -15,6 +15,11 @@ public class EmptyResponse extends HttpResponse { super(status); } + public EmptyResponse() { + this(200); + } + + @Override public void render(OutputStream outputStream) throws IOException { // NOP } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java index f4a1001d9ff..56b7ffd01f9 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/SystemApplication.java @@ -33,7 +33,7 @@ public enum SystemApplication { tenantHost(InfrastructureApplication.TENANT_HOST); /** The tenant owning all system applications */ - public static final TenantName TENANT = TenantName.from(Constants.TENANT_NAME); + public static final TenantName TENANT = TenantName.from("hosted-vespa"); private final InfrastructureApplication application; private final List<SystemApplication> dependencies; @@ -95,8 +95,4 @@ public enum SystemApplication { return Text.format("system application %s of type %s", id(), nodeType()); } - private static class Constants { - private static final String TENANT_NAME = "hosted-vespa"; - } - } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/TrafficShareUpdater.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/TrafficShareUpdater.java index aea01ae36d3..80647e6ea0a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/TrafficShareUpdater.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/TrafficShareUpdater.java @@ -66,6 +66,8 @@ public class TrafficShareUpdater extends ControllerMaintainer { double successFactor = asSuccessFactor(attempts, failures); if ( successFactor == 0 ) log.log(Level.WARNING, "Could not update traffic share on any applications", lastException); + else if ( successFactor < 0.9 ) + log.log(Level.FINE, "Could not update traffic share on any applications", lastException); return successFactor; } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/FormattedNotification.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/FormattedNotification.java index 8a6243a7224..5e36d6d6499 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/FormattedNotification.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/FormattedNotification.java @@ -9,32 +9,13 @@ import java.util.Objects; * * @author enygaard */ -public class FormattedNotification { - private final String prettyType; - private final String messagePrefix; - private final URI uri; - private final Notification notification; +public record FormattedNotification(Notification notification, String prettyType, String messagePrefix, URI uri) { - public FormattedNotification(Notification notification, String prettyType, String messagePrefix, URI uri) { - this.prettyType = Objects.requireNonNull(prettyType); - this.messagePrefix = Objects.requireNonNull(messagePrefix); - this.uri = Objects.requireNonNull(uri); - this.notification = Objects.requireNonNull(notification); + public FormattedNotification { + Objects.requireNonNull(prettyType); + Objects.requireNonNull(messagePrefix); + Objects.requireNonNull(uri); + Objects.requireNonNull(notification); } - public String prettyType() { - return prettyType; - } - - public String messagePrefix() { - return messagePrefix; - } - - public URI uri() { - return uri; - } - - public Notification notification() { - return notification; - } -}
\ No newline at end of file +} diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/Notification.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/Notification.java index da423995b7e..53450783c8e 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/Notification.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/Notification.java @@ -13,12 +13,7 @@ import java.util.Objects; * * @author freva */ -public class Notification { - private final Instant at; - private final Type type; - private final Level level; - private final NotificationSource source; - private final List<String> messages; +public record Notification(Instant at, com.yahoo.vespa.hosted.controller.notification.Notification.Type type, com.yahoo.vespa.hosted.controller.notification.Notification.Level level, NotificationSource source, List<String> messages) { public Notification(Instant at, Type type, Level level, NotificationSource source, List<String> messages) { this.at = Objects.requireNonNull(at, "at cannot be null"); @@ -29,37 +24,6 @@ public class Notification { if (messages.size() < 1) throw new IllegalArgumentException("messages cannot be empty"); } - public Instant at() { return at; } - public Type type() { return type; } - public Level level() { return level; } - public NotificationSource source() { return source; } - public List<String> messages() { return messages; } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Notification that = (Notification) o; - return at.equals(that.at) && type == that.type && level == that.level && - source.equals(that.source) && messages.equals(that.messages); - } - - @Override - public int hashCode() { - return Objects.hash(at, type, level, source, messages); - } - - @Override - public String toString() { - return "Notification{" + - "at=" + at + - ", type=" + type + - ", level=" + level + - ", source=" + source + - ", messages=" + messages + - '}'; - } - public enum Level { // Must be ordered in order of importance info, warning, error @@ -67,22 +31,34 @@ public class Notification { public enum Type { - /** Related to contents of application package, e.g., usage of deprecated features/syntax */ + /** + * Related to contents of application package, e.g., usage of deprecated features/syntax + */ applicationPackage, - /** Related to contents of application package detectable by the controller on submission */ + /** + * Related to contents of application package detectable by the controller on submission + */ submission, - /** Related to contents of application test package, e.g., mismatch between deployment spec and provided tests */ + /** + * Related to contents of application test package, e.g., mismatch between deployment spec and provided tests + */ testPackage, - /** Related to deployment of application, e.g., system test failure, node allocation failure, internal errors, etc. */ + /** + * Related to deployment of application, e.g., system test failure, node allocation failure, internal errors, etc. + */ deployment, - /** Application cluster is (near) external feed blocked */ + /** + * Application cluster is (near) external feed blocked + */ feedBlock, - /** Application cluster is reindexing document(s) */ + /** + * Application cluster is reindexing document(s) + */ reindex } 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 bc7e3f0e7d0..54d219a2a6d 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 @@ -29,6 +29,7 @@ import com.yahoo.config.provision.ZoneEndpoint.AllowedUrn; import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.container.handler.metrics.JsonResponse; +import com.yahoo.container.jdisc.EmptyResponse; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.ThreadedHttpRequestHandler; @@ -50,7 +51,6 @@ import com.yahoo.slime.SlimeUtils; import com.yahoo.text.Text; import com.yahoo.vespa.athenz.api.OAuthCredentials; import com.yahoo.vespa.athenz.client.zms.ZmsClientException; -import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.hosted.controller.Application; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.Instance; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/EmptyResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/EmptyResponse.java deleted file mode 100644 index dbd4250669c..00000000000 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/EmptyResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi.application; - -import com.yahoo.container.jdisc.HttpResponse; - -import java.io.OutputStream; - -/** - * @author bratseth - */ -public class EmptyResponse extends HttpResponse { - - public EmptyResponse() { - super(200); - } - - @Override - public void render(OutputStream stream) {} - -} diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/CsvResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/CsvResponse.java index 3643626761d..e97a51e58a2 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/CsvResponse.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/billing/CsvResponse.java @@ -9,7 +9,11 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.List; +/** + * @author ogronnesby + */ class CsvResponse extends HttpResponse { + private final String[] header; private final List<Object[]> rows; @@ -31,4 +35,5 @@ class CsvResponse extends HttpResponse { public String getContentType() { return "text/csv; encoding=utf-8"; } + } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java index 5148577880f..6d19316efd7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/changemanagement/ChangeManagementApiHandler.java @@ -46,18 +46,13 @@ public class ChangeManagementApiHandler extends AuditLoggingRequestHandler { @Override public HttpResponse auditAndHandle(HttpRequest request) { try { - switch (request.getMethod()) { - case GET: - return get(request); - case POST: - return post(request); - case PATCH: - return patch(request); - case DELETE: - return delete(request); - default: - return ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is unsupported"); - } + return switch (request.getMethod()) { + case GET -> get(request); + case POST -> post(request); + case PATCH -> patch(request); + case DELETE -> delete(request); + default -> ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is unsupported"); + }; } catch (IllegalArgumentException e) { return ErrorResponse.badRequest(Exceptions.toMessageString(e)); } catch (RuntimeException e) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/configserver/ConfigServerApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/configserver/ConfigServerApiHandler.java index e764fed4653..3c832dc8873 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/configserver/ConfigServerApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/configserver/ConfigServerApiHandler.java @@ -55,17 +55,11 @@ public class ConfigServerApiHandler extends AuditLoggingRequestHandler { @Override public HttpResponse auditAndHandle(HttpRequest request) { try { - switch (request.getMethod()) { - case GET: - return get(request); - case POST: - case PUT: - case DELETE: - case PATCH: - return proxy(request); - default: - return ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is unsupported"); - } + return switch (request.getMethod()) { + case GET -> get(request); + case POST, PUT, DELETE, PATCH -> proxy(request); + default -> ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is unsupported"); + }; } catch (IllegalArgumentException e) { return ErrorResponse.badRequest(Exceptions.toMessageString(e)); } catch (RuntimeException e) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java index 74a28276c79..c6eaf5abef7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java @@ -52,10 +52,10 @@ public class BadgeApiHandler extends ThreadedHttpRequestHandler { public HttpResponse handle(HttpRequest request) { Method method = request.getMethod(); try { - switch (method) { - case GET: return get(request); - default: return ErrorResponse.methodNotAllowed("Method '" + method + "' is unsupported"); - } + return switch (method) { + case GET -> get(request); + default -> ErrorResponse.methodNotAllowed("Method '" + method + "' is unsupported"); + }; } catch (IllegalArgumentException|IllegalStateException e) { return ErrorResponse.badRequest(Exceptions.toMessageString(e)); } catch (RuntimeException e) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/Badges.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/Badges.java index eed12f61a76..814241a765c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/Badges.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/Badges.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.hosted.controller.restapi.deployment; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.SystemName; import com.yahoo.slime.ArrayTraverser; import com.yahoo.slime.SlimeUtils; import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType; @@ -51,18 +50,16 @@ public class Badges { } static String colorOf(Run run, Optional<RunStatus> previous) { - switch (run.status()) { - case running: switch (previous.orElse(RunStatus.success)) { - case success: return "url(#run-on-success)"; - case aborted: - case noTests: return "url(#run-on-warning)"; - default: return "url(#run-on-failure)"; - } - case success: return success; - case aborted: - case noTests: return warning; - default: return failure; - } + return switch (run.status()) { + case running -> switch (previous.orElse(RunStatus.success)) { + case success -> "url(#run-on-success)"; + case aborted, noTests -> "url(#run-on-warning)"; + default -> "url(#run-on-failure)"; + }; + case success -> success; + case aborted, noTests -> warning; + default -> failure; + }; } static String nameOf(JobType type) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/CliApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/CliApiHandler.java index 336352e931a..c67d0d04938 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/CliApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/CliApiHandler.java @@ -34,10 +34,10 @@ public class CliApiHandler extends ThreadedHttpRequestHandler { @Override public HttpResponse handle(HttpRequest request) { try { - switch (request.getMethod()) { - case GET: return get(request); - default: return ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is not supported"); - } + return switch (request.getMethod()) { + case GET -> get(request); + default -> ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is not supported"); + }; } catch (IllegalArgumentException e) { return ErrorResponse.badRequest(Exceptions.toMessageString(e)); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java index 6946efdbe2a..759b2366229 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java @@ -5,6 +5,7 @@ import com.yahoo.component.Version; import com.yahoo.config.application.api.DeploymentInstanceSpec; import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.container.jdisc.EmptyResponse; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.ThreadedHttpRequestHandler; @@ -25,7 +26,6 @@ import com.yahoo.vespa.hosted.controller.deployment.Run; import com.yahoo.vespa.hosted.controller.deployment.RunStatus; import com.yahoo.vespa.hosted.controller.deployment.Versions; import com.yahoo.vespa.hosted.controller.restapi.ErrorResponses; -import com.yahoo.vespa.hosted.controller.restapi.application.EmptyResponse; import com.yahoo.vespa.hosted.controller.versions.DeploymentStatistics; import com.yahoo.vespa.hosted.controller.versions.VespaVersion; import com.yahoo.yolean.Exceptions; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java index e23f0205e5a..c25502ab9bf 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java @@ -6,7 +6,6 @@ import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.Payload; import com.yahoo.component.annotation.Inject; import com.yahoo.config.provision.ApplicationName; -import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.jdisc.Response; @@ -33,7 +32,6 @@ import com.yahoo.vespa.hosted.controller.tenant.Tenant; import com.yahoo.yolean.Exceptions; import java.net.URI; -import java.security.Principal; import java.security.cert.X509Certificate; import java.time.Instant; import java.util.ArrayList; @@ -64,7 +62,6 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { private final AthenzFacade athenz; private final TenantController tenants; private final ExecutorService executor; - private final SystemName systemName; private final ZoneRegistry zones; @Inject @@ -72,7 +69,6 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { this.athenz = new AthenzFacade(athenzClientFactory); this.tenants = controller.tenants(); this.executor = Executors.newCachedThreadPool(); - this.systemName = controller.system(); this.zones = controller.zoneRegistry(); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java index c2e926f777b..a9787e28113 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.user; import com.yahoo.component.annotation.Inject; import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.TenantName; +import com.yahoo.container.jdisc.EmptyResponse; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.ThreadedHttpRequestHandler; @@ -37,7 +38,6 @@ import com.yahoo.vespa.hosted.controller.api.role.SimplePrincipal; import com.yahoo.vespa.hosted.controller.api.role.TenantRole; import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId; import com.yahoo.vespa.hosted.controller.restapi.ErrorResponses; -import com.yahoo.vespa.hosted.controller.restapi.application.EmptyResponse; import com.yahoo.vespa.hosted.controller.tenant.Tenant; import com.yahoo.yolean.Exceptions; diff --git a/document/src/vespa/document/base/exceptions.cpp b/document/src/vespa/document/base/exceptions.cpp index b0c2cf05eb1..f1ea0645eb8 100644 --- a/document/src/vespa/document/base/exceptions.cpp +++ b/document/src/vespa/document/base/exceptions.cpp @@ -61,6 +61,8 @@ DataTypeNotFoundException::DataTypeNotFoundException(const vespalib::string& nam { } +DataTypeNotFoundException::~DataTypeNotFoundException() = default; + AnnotationTypeNotFoundException::AnnotationTypeNotFoundException( int id, const vespalib::string& location) : Exception(vespalib::make_string("Data type with id %d not found", id), @@ -68,6 +70,8 @@ AnnotationTypeNotFoundException::AnnotationTypeNotFoundException( { } +AnnotationTypeNotFoundException::~AnnotationTypeNotFoundException() = default; + FieldNotFoundException:: FieldNotFoundException(const vespalib::string& fieldName, const vespalib::string& location) diff --git a/document/src/vespa/document/base/exceptions.h b/document/src/vespa/document/base/exceptions.h index 6e91b5c08ee..4358daed5ec 100644 --- a/document/src/vespa/document/base/exceptions.h +++ b/document/src/vespa/document/base/exceptions.h @@ -22,7 +22,7 @@ public: InvalidDataTypeException(const DataType &actual, const DataType &wanted, const vespalib::string & location); - virtual ~InvalidDataTypeException(); + ~InvalidDataTypeException() override; const DataType& getActualDataType() const { return _actual; } const DataType& getExpectedDataType() const { return _expected; } @@ -48,7 +48,7 @@ public: InvalidDataTypeConversionException(const DataType &actual, const DataType &wanted, const vespalib::string & location); - virtual ~InvalidDataTypeConversionException() throw(); + ~InvalidDataTypeConversionException() override; const DataType& getActualDataType() const { return _actual; } const DataType& getExpectedDataType() const { return _expected; } @@ -93,6 +93,7 @@ class DataTypeNotFoundException : public vespalib::Exception public: DataTypeNotFoundException(int id, const vespalib::string& location); DataTypeNotFoundException(const vespalib::string& name, const vespalib::string& location); + ~DataTypeNotFoundException() override; VESPA_DEFINE_EXCEPTION_SPINE(DataTypeNotFoundException); }; @@ -107,6 +108,7 @@ class AnnotationTypeNotFoundException : public vespalib::Exception { public: AnnotationTypeNotFoundException(int id, const vespalib::string& location); + ~AnnotationTypeNotFoundException() override; VESPA_DEFINE_EXCEPTION_SPINE(AnnotationTypeNotFoundException); }; diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index 9b1a5a504d4..6fc45c31ff8 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -46,12 +46,6 @@ public class Flags { private static volatile TreeMap<FlagId, FlagDefinition> flags = new TreeMap<>(); - public static final UnboundBooleanFlag RECURSIVE_WANT_TO_DEPROVISION = defineFeatureFlag( - "recursive-want-to-deprovision", true, - List.of("hakonhall"), "2023-01-09", "2023-02-08", - "Whether setting or clearing wantToDeprovision on a host should be applied to the children.", - "Takes effect immediately."); - public static final UnboundDoubleFlag DEFAULT_TERM_WISE_LIMIT = defineDoubleFlag( "default-term-wise-limit", 1.0, List.of("baldersheim"), "2020-12-02", "2023-12-31", diff --git a/fsa/src/libfsa/automaton-alternate.h b/fsa/src/libfsa/automaton-alternate.h index db17306376b..16312e366fe 100644 --- a/fsa/src/libfsa/automaton-alternate.h +++ b/fsa/src/libfsa/automaton-alternate.h @@ -436,14 +436,14 @@ private: struct rebind { using other = MMapArenaAllocator<_Tp1>; }; - MMapArenaAllocator() throw(): _chunks(), _size(0) { } + MMapArenaAllocator() noexcept : _chunks(), _size(0) { } - MMapArenaAllocator(const MMapArenaAllocator&) throw(): _chunks(), _size(0) { } + MMapArenaAllocator(const MMapArenaAllocator&) noexcept : _chunks(), _size(0) { } template<typename _Tp1> - MMapArenaAllocator(const MMapArenaAllocator<_Tp1>&) throw(): _chunks(), _size(0) { } + MMapArenaAllocator(const MMapArenaAllocator<_Tp1>&) noexcept : _chunks(), _size(0) { } - ~MMapArenaAllocator() throw() { release(); } + ~MMapArenaAllocator() noexcept { release(); } pointer address(reference __x) const { return &__x; } @@ -489,7 +489,7 @@ private: } size_type - max_size() const throw() + max_size() const noexcept { return _CAPACITY / sizeof(_Tp); } void diff --git a/logd/src/logd/exceptions.h b/logd/src/logd/exceptions.h index f2242764060..acee03dcda5 100644 --- a/logd/src/logd/exceptions.h +++ b/logd/src/logd/exceptions.h @@ -12,7 +12,7 @@ private: public: MsgException(const std::string & s) : _string(s) {} ~MsgException() override {} - const char *what() const throw() override { return _string.c_str(); } + const char *what() const noexcept override { return _string.c_str(); } }; class ConnectionException : public MsgException diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java index ec1e42a911e..e363e85b898 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java @@ -23,8 +23,8 @@ import com.yahoo.vespa.hosted.node.admin.container.ContainerOperations; import com.yahoo.vespa.hosted.node.admin.container.ContainerResources; import com.yahoo.vespa.hosted.node.admin.container.RegistryCredentials; import com.yahoo.vespa.hosted.node.admin.container.RegistryCredentialsProvider; -import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.ContainerWireguardTask; +import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.identity.CredentialsMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.servicedump.VespaServiceDumper; @@ -72,7 +72,7 @@ public class NodeAgentImpl implements NodeAgent { private final Duration warmUpDuration; private final DoubleFlag containerCpuCap; private final VespaServiceDumper serviceDumper; - private final Optional<ContainerWireguardTask> wireguardMaintainer; + private final List<ContainerWireguardTask> wireguardTasks; private Thread loopThread; private ContainerState containerState = UNKNOWN; @@ -108,10 +108,10 @@ public class NodeAgentImpl implements NodeAgent { RegistryCredentialsProvider registryCredentialsProvider, StorageMaintainer storageMaintainer, FlagSource flagSource, List<CredentialsMaintainer> credentialsMaintainers, Optional<AclMaintainer> aclMaintainer, Optional<HealthChecker> healthChecker, Clock clock, - VespaServiceDumper serviceDumper, Optional<ContainerWireguardTask> wireguardMaintainer) { + VespaServiceDumper serviceDumper, List<ContainerWireguardTask> wireguardTasks) { this(contextSupplier, nodeRepository, orchestrator, containerOperations, registryCredentialsProvider, storageMaintainer, flagSource, credentialsMaintainers, aclMaintainer, healthChecker, clock, - DEFAULT_WARM_UP_DURATION, serviceDumper, wireguardMaintainer); + DEFAULT_WARM_UP_DURATION, serviceDumper, wireguardTasks); } public NodeAgentImpl(NodeAgentContextSupplier contextSupplier, NodeRepository nodeRepository, @@ -120,7 +120,7 @@ public class NodeAgentImpl implements NodeAgent { FlagSource flagSource, List<CredentialsMaintainer> credentialsMaintainers, Optional<AclMaintainer> aclMaintainer, Optional<HealthChecker> healthChecker, Clock clock, Duration warmUpDuration, VespaServiceDumper serviceDumper, - Optional<ContainerWireguardTask> wireguardMaintainer) { + List<ContainerWireguardTask> wireguardTasks) { this.contextSupplier = contextSupplier; this.nodeRepository = nodeRepository; this.orchestrator = orchestrator; @@ -134,7 +134,7 @@ public class NodeAgentImpl implements NodeAgent { this.warmUpDuration = warmUpDuration; this.containerCpuCap = PermanentFlags.CONTAINER_CPU_CAP.bindTo(flagSource); this.serviceDumper = serviceDumper; - this.wireguardMaintainer = wireguardMaintainer; + this.wireguardTasks = new ArrayList<>(wireguardTasks); } @Override @@ -498,7 +498,7 @@ public class NodeAgentImpl implements NodeAgent { } aclMaintainer.ifPresent(maintainer -> maintainer.converge(context)); - wireguardMaintainer.ifPresent(maintainer -> maintainer.converge(context)); + wireguardTasks.forEach(task -> task.converge(context)); startServicesIfNeeded(context); resumeNodeIfNeeded(context); if (healthChecker.isPresent()) { diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java index 2f9b282c44e..7676d0e1790 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integration/ContainerTester.java @@ -95,7 +95,7 @@ public class ContainerTester implements AutoCloseable { new NodeAgentImpl(contextSupplier, nodeRepository, orchestrator, containerOperations, () -> RegistryCredentials.none, storageMaintainer, flagSource, Collections.emptyList(), Optional.empty(), Optional.empty(), clock, Duration.ofSeconds(-1), - VespaServiceDumper.DUMMY_INSTANCE, Optional.empty()) { + VespaServiceDumper.DUMMY_INSTANCE, List.of()) { @Override public void converge(NodeAgentContext context) { super.converge(context); phaser.arriveAndAwaitAdvance(); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java index fb132c9b717..b8b72308bdd 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java @@ -789,7 +789,7 @@ public class NodeAgentImplTest { return new NodeAgentImpl(contextSupplier, nodeRepository, orchestrator, containerOperations, () -> RegistryCredentials.none, storageMaintainer, flagSource, List.of(credentialsMaintainer), Optional.of(aclMaintainer), Optional.of(healthChecker), - clock, warmUpDuration, VespaServiceDumper.DUMMY_INSTANCE, Optional.empty()); + clock, warmUpDuration, VespaServiceDumper.DUMMY_INSTANCE, List.of()); } private void mockGetContainer(DockerImage dockerImage, boolean isRunning) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java index 1f0244c8e40..64f3ff9f5ba 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodePatcher.java @@ -14,9 +14,6 @@ import com.yahoo.slime.Inspector; import com.yahoo.slime.ObjectTraverser; import com.yahoo.slime.SlimeUtils; import com.yahoo.slime.Type; -import com.yahoo.vespa.flags.BooleanFlag; -import com.yahoo.vespa.flags.FlagSource; -import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.hosted.provision.LockedNodeList; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; @@ -68,13 +65,11 @@ public class NodePatcher { private final NodeRepository nodeRepository; private final NodeFlavors nodeFlavors; private final Clock clock; - private final BooleanFlag recursiveWantToDeprovision; - public NodePatcher(NodeFlavors nodeFlavors, NodeRepository nodeRepository, FlagSource flagSource) { + public NodePatcher(NodeFlavors nodeFlavors, NodeRepository nodeRepository) { this.nodeRepository = nodeRepository; this.nodeFlavors = nodeFlavors; this.clock = nodeRepository.clock(); - this.recursiveWantToDeprovision = Flags.RECURSIVE_WANT_TO_DEPROVISION.bindTo(flagSource); } /** @@ -200,7 +195,6 @@ public class NodePatcher { // These needs to be handled as one, because certain combinations are not allowed. return node.withWantToRetire(asOptionalBoolean(root.field(WANT_TO_RETIRE)).orElseGet(node.status()::wantToRetire), asOptionalBoolean(root.field(WANT_TO_DEPROVISION)) - .filter(want -> recursiveWantToDeprovision.value() || !applyingAsChild) .orElseGet(node.status()::wantToDeprovision), asOptionalBoolean(root.field(WANT_TO_REBUILD)) .filter(want -> !applyingAsChild) diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java index fd466108063..d09ff1b84fc 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java @@ -16,7 +16,6 @@ import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.PermanentFlags; import com.yahoo.vespa.flags.StringFlag; import com.yahoo.vespa.hosted.provision.Node; -import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.node.Address; import com.yahoo.vespa.hosted.provision.node.Allocation; @@ -107,17 +106,11 @@ class NodesResponse extends SlimeJsonResponse { /** Outputs the nodes in the given states to a node array */ private void nodesToSlime(Set<Node.State> states, Cursor parentObject) { Cursor nodeArray = parentObject.setArray("nodes"); - NodeList nodes = nodeRepository.nodes().list() - .state(states) - .sortedBy(Comparator.comparing(Node::hostname)); - toSlime(nodes, nodeArray); - } - - private void toSlime(NodeList nodes, Cursor array) { - for (Node node : nodes) { - if ( ! filter.test(node)) continue; - toSlime(node, recursive, array.addObject()); - } + nodeRepository.nodes().list() + .state(states) + .matching(filter) + .sortedBy(Comparator.comparing(Node::hostname)) + .forEach(node -> toSlime(node, recursive, nodeArray.addObject())); } private void nodeToSlime(String hostname, Cursor object) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java index cde951d1bf1..b1a66e34c9e 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiHandler.java @@ -26,7 +26,6 @@ import com.yahoo.slime.Cursor; import com.yahoo.slime.Inspector; import com.yahoo.slime.Slime; import com.yahoo.slime.SlimeUtils; -import com.yahoo.vespa.flags.FlagSource; import com.yahoo.vespa.hosted.provision.NoSuchNodeException; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; @@ -76,16 +75,13 @@ public class NodesV2ApiHandler extends ThreadedHttpRequestHandler { private final Orchestrator orchestrator; private final NodeRepository nodeRepository; private final NodeFlavors nodeFlavors; - private final FlagSource flagSource; @Inject - public NodesV2ApiHandler(ThreadedHttpRequestHandler.Context parentCtx, Orchestrator orchestrator, - NodeRepository nodeRepository, NodeFlavors flavors, FlagSource flagSource) { + public NodesV2ApiHandler(Context parentCtx, Orchestrator orchestrator, NodeRepository nodeRepository, NodeFlavors flavors) { super(parentCtx); this.orchestrator = orchestrator; this.nodeRepository = nodeRepository; this.nodeFlavors = flavors; - this.flagSource = flagSource; } @Override @@ -172,7 +168,7 @@ public class NodesV2ApiHandler extends ThreadedHttpRequestHandler { private HttpResponse handlePATCH(HttpRequest request) { Path path = new Path(request.getUri()); if (path.matches("/nodes/v2/node/{hostname}")) { - NodePatcher patcher = new NodePatcher(nodeFlavors, nodeRepository, flagSource); + NodePatcher patcher = new NodePatcher(nodeFlavors, nodeRepository); String hostname = path.get("hostname"); if (isTenantPeer(request)) { patcher.patchFromUntrustedTenantHost(hostname, request.getData()); diff --git a/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp b/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp index 88d0752461b..8dc2551d96b 100644 --- a/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp +++ b/searchcore/src/tests/proton/attribute/attribute_manager/attribute_manager_test.cpp @@ -867,7 +867,7 @@ TEST_F("require that shrink flushtarget is handed over to new attribute manager" am1->addAttribute({"a1", INT32_SINGLE}, 4); AttrSpecList newSpec; newSpec.emplace_back("a1", INT32_SINGLE); - auto am2 = am1->create(AttrMgrSpec(std::move(newSpec), 5, 20)); + auto am2 = am1->prepare_create(AttrMgrSpec(std::move(newSpec), 5, 20))->create(5, 20); auto am3 = std::dynamic_pointer_cast<AttributeManager>(am2); TEST_DO(assertShrinkTargetSerial(*am3, "a1", 3)); EXPECT_EQUAL(am1->getShrinker("a1"), am3->getShrinker("a1")); diff --git a/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp b/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp index d7ce042a4d3..9639f2c591e 100644 --- a/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp +++ b/searchcore/src/tests/proton/documentdb/configurer/configurer_test.cpp @@ -2,24 +2,33 @@ #include <vespa/vespalib/testkit/testapp.h> +#include <vespa/config-summary.h> #include <vespa/document/datatype/documenttype.h> #include <vespa/document/repo/documenttyperepo.h> +#include <vespa/eval/eval/value_cache/constant_value.h> +#include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> #include <vespa/searchcore/proton/attribute/attributemanager.h> #include <vespa/searchcore/proton/attribute/imported_attributes_repo.h> #include <vespa/searchcore/proton/bucketdb/bucket_db_owner.h> +#include <vespa/searchcore/proton/common/docid_limit.h> +#include <vespa/searchcore/proton/common/pendinglidtracker.h> #include <vespa/searchcore/proton/docsummary/summarymanager.h> +#include <vespa/searchcore/proton/documentmetastore/documentmetastorecontext.h> #include <vespa/searchcore/proton/index/index_writer.h> #include <vespa/searchcore/proton/index/indexmanager.h> #include <vespa/searchcore/proton/matching/querylimiter.h> +#include <vespa/searchcore/proton/matching/ranking_assets_repo.h> #include <vespa/searchcore/proton/matching/sessionmanager.h> #include <vespa/searchcore/proton/reference/dummy_gid_to_lid_change_handler.h> +#include <vespa/searchcore/proton/reference/i_document_db_reference_resolver.h> #include <vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.h> -#include <vespa/searchcore/proton/server/attribute_writer_factory.h> #include <vespa/searchcore/proton/server/document_subdb_reconfig.h> #include <vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.h> #include <vespa/searchcore/proton/server/reconfig_params.h> #include <vespa/searchcore/proton/server/searchable_doc_subdb_configurer.h> +#include <vespa/searchcore/proton/server/searchview.h> +#include <vespa/searchcore/proton/server/searchable_feed_view.h> #include <vespa/searchcore/proton/server/summaryadapter.h> #include <vespa/searchcore/proton/test/documentdb_config_builder.h> #include <vespa/searchcore/proton/test/mock_gid_to_lid_change_handler.h> @@ -28,6 +37,7 @@ #include <vespa/searchlib/attribute/interlock.h> #include <vespa/searchlib/index/dummyfileheadercontext.h> #include <vespa/searchlib/transactionlog/nosyncproxy.h> +#include <vespa/searchsummary/config/config-juniperrc.h> #include <vespa/vespalib/util/size_literals.h> #include <vespa/vespalib/util/testclock.h> #include <vespa/vespalib/util/threadstackexecutor.h> @@ -80,8 +90,8 @@ createRepo() struct ViewPtrs { - SearchView::SP sv; - SearchableFeedView::SP fv; + std::shared_ptr<SearchView> sv; + std::shared_ptr<SearchableFeedView> fv; ~ViewPtrs(); }; @@ -92,7 +102,7 @@ struct ViewSet IndexManagerDummyReconfigurer _reconfigurer; DummyFileHeaderContext _fileHeaderContext; TransportAndExecutorService _service; - SearchableFeedView::SerialNum serialNum; + SerialNum serialNum; std::shared_ptr<const DocumentTypeRepo> repo; DocTypeName _docTypeName; DocIdLimit _docIdLimit; @@ -100,8 +110,8 @@ struct ViewSet ISummaryManager::SP _summaryMgr; proton::IDocumentMetaStoreContext::SP _dmsc; std::shared_ptr<IGidToLidChangeHandler> _gidToLidChangeHandler; - VarHolder<SearchView::SP> searchView; - VarHolder<SearchableFeedView::SP> feedView; + VarHolder<std::shared_ptr<SearchView>> searchView; + VarHolder<std::shared_ptr<SearchableFeedView>> feedView; HwInfo _hwInfo; ViewSet(); ~ViewSet(); @@ -170,9 +180,9 @@ struct Fixture SerialNum serial_num); IReprocessingInitializer::UP reconfigure(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, - AttributeCollectionSpec&& attr_spec, const ReconfigParams& reconfig_params, IDocumentDBReferenceResolver& resolver, + uint32_t docid_limit, SerialNum serial_num); }; @@ -246,20 +256,26 @@ Fixture::reconfigure(const DocumentDBConfig& new_config_snapshot, IDocumentDBReferenceResolver& resolver, SerialNum serial_num) { - auto prepared_reconfig = _configurer->prepare_reconfig(new_config_snapshot, old_config_snapshot, reconfig_params, serial_num); + EXPECT_FALSE(reconfig_params.shouldAttributeManagerChange()); + uint32_t docid_limit = 1; + AttributeCollectionSpecFactory attr_spec_factory(AllocStrategy(), false); + auto prepared_reconfig = _configurer->prepare_reconfig(new_config_snapshot, old_config_snapshot, attr_spec_factory, reconfig_params, docid_limit, serial_num); + prepared_reconfig->complete(docid_limit, serial_num); _configurer->reconfigure(new_config_snapshot, old_config_snapshot, reconfig_params, resolver, *prepared_reconfig, serial_num); } IReprocessingInitializer::UP Fixture::reconfigure(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, - AttributeCollectionSpec&& attr_spec, const ReconfigParams& reconfig_params, IDocumentDBReferenceResolver& resolver, + uint32_t docid_limit, SerialNum serial_num) { - auto prepared_reconfig = _configurer->prepare_reconfig(new_config_snapshot, old_config_snapshot, reconfig_params, serial_num); - return _configurer->reconfigure(new_config_snapshot, old_config_snapshot, std::move(attr_spec), reconfig_params, resolver, *prepared_reconfig, serial_num); + AttributeCollectionSpecFactory attr_spec_factory(AllocStrategy(), false); + auto prepared_reconfig = _configurer->prepare_reconfig(new_config_snapshot, old_config_snapshot, attr_spec_factory, reconfig_params, docid_limit, serial_num); + prepared_reconfig->complete(docid_limit, serial_num); + return _configurer->reconfigure(new_config_snapshot, old_config_snapshot, reconfig_params, resolver, *prepared_reconfig, serial_num); } using MySummaryAdapter = test::MockSummaryAdapter; @@ -318,7 +334,7 @@ struct FastAccessFixture FastAccessFixture() : _service(1), _view(_service.write()), - _configurer(_view._feedView, std::make_unique<AttributeWriterFactory>(), "test") + _configurer(_view._feedView, "test") { std::filesystem::remove_all(std::filesystem::path(BASE_DIR)); std::filesystem::create_directory(std::filesystem::path(BASE_DIR)); @@ -330,19 +346,21 @@ struct FastAccessFixture IReprocessingInitializer::UP reconfigure(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, - AttributeCollectionSpec&& attr_spec, + uint32_t docid_limit, SerialNum serial_num); }; IReprocessingInitializer::UP FastAccessFixture::reconfigure(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, - AttributeCollectionSpec&& attr_spec, + uint32_t docid_limit, SerialNum serial_num) { ReconfigParams reconfig_params{CCR()}; - auto prepared_reconfig = _configurer.prepare_reconfig(new_config_snapshot, old_config_snapshot, reconfig_params, serial_num); - return _configurer.reconfigure(new_config_snapshot, old_config_snapshot, std::move(attr_spec), *prepared_reconfig, serial_num); + AttributeCollectionSpecFactory attr_spec_factory(AllocStrategy(), true); + auto prepared_reconfig = _configurer.prepare_reconfig(new_config_snapshot, old_config_snapshot, attr_spec_factory, reconfig_params, docid_limit, serial_num); + prepared_reconfig->complete(docid_limit, serial_num); + return _configurer.reconfigure(new_config_snapshot, old_config_snapshot, *prepared_reconfig, serial_num); } DocumentDBConfig::SP @@ -509,8 +527,7 @@ TEST_F("require that we can reconfigure attribute manager", Fixture) // Use new config snapshot == old config snapshot (only relevant for reprocessing) SerialNum reconfig_serial_num = 0; f.reconfigure(*createConfig(), *createConfig(), - AttributeCollectionSpec(AttributeCollectionSpec::AttributeList(), 1, reconfig_serial_num), - params, f._resolver, reconfig_serial_num); + params, f._resolver, 1, reconfig_serial_num); ViewPtrs n = f._views.getViewPtrs(); { // verify search view @@ -548,8 +565,7 @@ checkAttributeWriterChangeOnRepoChange(Fixture &f, bool docTypeRepoChanged) // Use new config snapshot == old config snapshot (only relevant for reprocessing) SerialNum reconfig_serial_num = 0; f.reconfigure(*createConfig(), *createConfig(), - AttributeCollectionSpec(AttributeCollectionSpec::AttributeList(), 1, reconfig_serial_num), - params, f._resolver, reconfig_serial_num); + params, f._resolver, 1, reconfig_serial_num); auto newAttributeWriter = getAttributeWriter(f); if (docTypeRepoChanged) { EXPECT_NOT_EQUAL(oldAttributeWriter, newAttributeWriter); @@ -570,8 +586,7 @@ TEST_F("require that reconfigure returns reprocessing initializer when changing SerialNum reconfig_serial_num = 0; IReprocessingInitializer::UP init = f.reconfigure(*createConfig(), *createConfig(), - AttributeCollectionSpec(AttributeCollectionSpec::AttributeList(), 1, reconfig_serial_num), - params, f._resolver, reconfig_serial_num); + params, f._resolver, 1, reconfig_serial_num); EXPECT_TRUE(init.get() != nullptr); EXPECT_TRUE((dynamic_cast<AttributeReprocessingInitializer *>(init.get())) != nullptr); @@ -582,8 +597,7 @@ TEST_F("require that we can reconfigure attribute writer", FastAccessFixture) { FastAccessFeedView::SP o = f._view._feedView.get(); SerialNum reconfig_serial_num = 0; - f.reconfigure(*createConfig(), *createConfig(), - AttributeCollectionSpec(AttributeCollectionSpec::AttributeList(), 1, reconfig_serial_num), reconfig_serial_num); + f.reconfigure(*createConfig(), *createConfig(), 1, reconfig_serial_num); FastAccessFeedView::SP n = f._view._feedView.get(); FastAccessFeedViewComparer cmp(o, n); @@ -596,8 +610,7 @@ TEST_F("require that we can reconfigure attribute writer", FastAccessFixture) TEST_F("require that reconfigure returns reprocessing initializer", FastAccessFixture) { SerialNum reconfig_serial_num = 0; - IReprocessingInitializer::UP init = f.reconfigure(*createConfig(), *createConfig(), - AttributeCollectionSpec(AttributeCollectionSpec::AttributeList(), 1, reconfig_serial_num), reconfig_serial_num); + auto init = f.reconfigure(*createConfig(), *createConfig(), 1, reconfig_serial_num); EXPECT_TRUE(init.get() != nullptr); EXPECT_TRUE((dynamic_cast<AttributeReprocessingInitializer *>(init.get())) != nullptr); diff --git a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp index f49c46d81e8..db70aaaf200 100644 --- a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp +++ b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp @@ -380,6 +380,7 @@ struct FixtureBase MyDocumentDBReferenceResolver resolver; ReconfigParams reconfig_params(cmpResult); auto prepared_reconfig = _subDb.prepare_reconfig(*newCfg->_cfg, *_snapshot->_cfg, reconfig_params, serialNum); + _subDb.complete_prepare_reconfig(*prepared_reconfig, serialNum); auto tasks = _subDb.applyConfig(*newCfg->_cfg, *_snapshot->_cfg, serialNum, reconfig_params, resolver, *prepared_reconfig); prepared_reconfig.reset(); diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.cpp index 2be0e0a58f8..be43a5323bb 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "attribute_collection_spec_factory.h" +#include "attribute_collection_spec.h" #include <vespa/searchlib/attribute/configconverter.h> #include <vespa/searchcommon/attribute/config.h> diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h b/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h index 06b3f677640..185daa15f2f 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h @@ -2,15 +2,17 @@ #pragma once -#include "attribute_collection_spec.h" #include <vespa/searchcore/proton/common/alloc_strategy.h> #include <vespa/searchlib/common/serialnum.h> +#include <memory> #include <optional> namespace vespa::config::search::internal { class InternalAttributesType; }; namespace proton { +class AttributeCollectionSpec; + /** * A factory for generating an AttributeCollectionSpec based on AttributesConfig * from the config server. diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.cpp index 06c03c80785..4638dd476b0 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.cpp @@ -16,7 +16,7 @@ AttributeManagerReconfig::AttributeManagerReconfig(std::shared_ptr<AttributeMana AttributeManagerReconfig::~AttributeManagerReconfig() = default; -std::shared_ptr<AttributeManager> +std::shared_ptr<IAttributeManager> AttributeManagerReconfig::create(uint32_t docid_limit, search::SerialNum serial_num) { assert(_mgr); diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.h b/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.h index 9e4f8b71a7a..027b96b4f63 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/attribute_manager_reconfig.h @@ -2,9 +2,8 @@ #pragma once -#include <vespa/searchlib/common/serialnum.h> +#include "i_attribute_manager_reconfig.h" #include <memory> -#include <optional> namespace proton { @@ -15,14 +14,14 @@ class SequentialAttributesInitializer; * Class representing the result of the prepare step of an AttributeManager * reconfig. */ -class AttributeManagerReconfig { +class AttributeManagerReconfig : public IAttributeManagerReconfig { std::shared_ptr<AttributeManager> _mgr; std::unique_ptr<SequentialAttributesInitializer> _initializer; public: AttributeManagerReconfig(std::shared_ptr<AttributeManager> mgr, std::unique_ptr<SequentialAttributesInitializer> initializer); - ~AttributeManagerReconfig(); - std::shared_ptr<AttributeManager> create(uint32_t docid_limit, search::SerialNum serial_num); + ~AttributeManagerReconfig() override; + std::shared_ptr<IAttributeManager> create(uint32_t docid_limit, search::SerialNum serial_num) override; }; } diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp index dd6cc1bdb85..161a4294908 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp @@ -499,7 +499,7 @@ AttributeManager::createContext() const return std::make_unique<AttributeContext>(*this); } -std::unique_ptr<AttributeManagerReconfig> +std::unique_ptr<IAttributeManagerReconfig> AttributeManager::prepare_create(Spec&& spec) const { auto initializer = std::make_unique<SequentialAttributesInitializer>(spec.getDocIdLimit()); @@ -507,16 +507,6 @@ AttributeManager::prepare_create(Spec&& spec) const return std::make_unique<AttributeManagerReconfig>(std::move(result), std::move(initializer)); } -proton::IAttributeManager::SP -AttributeManager::create(Spec&& spec) const -{ - assert(spec.getCurrentSerialNum().has_value()); - auto docid_limit = spec.getDocIdLimit(); - auto serial_num = spec.getCurrentSerialNum().value(); - auto prepared_result = prepare_create(std::move(spec)); - return prepared_result->create(docid_limit, serial_num); -} - std::vector<IFlushTarget::SP> AttributeManager::getFlushTargets() const { diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h index c8c5da7f4e4..c924c1c5b20 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h @@ -2,10 +2,8 @@ #pragma once -#include "attribute_collection_spec.h" -#include "i_attribute_factory.h" #include "i_attribute_manager.h" -#include "i_attribute_initializer_registry.h" +#include "attribute_collection_spec.h" #include <set> #include <vespa/searchlib/common/tunefileinfo.h> #include <vespa/vespalib/stllike/hash_map.h> @@ -21,8 +19,13 @@ namespace vespalib { class ThreadExecutor; } namespace proton { +class AttributeCollectionSpec; class AttributeDiskLayout; +class AttributeInitializerResult; +class AttributeSpec; class FlushableAttribute; +struct IAttributeFactory; +struct IAttributeInitializerRegistry; class ShrinkLidSpaceFlushTarget; /** @@ -81,7 +84,7 @@ private: vespalib::string _documentSubDbName; const search::TuneFileAttributes _tuneFileAttributes; const search::common::FileHeaderContext &_fileHeaderContext; - IAttributeFactory::SP _factory; + std::shared_ptr<IAttributeFactory> _factory; std::shared_ptr<search::attribute::Interlock> _interlock; vespalib::ISequencedTaskExecutor &_attributeFieldWriter; vespalib::Executor& _shared_executor; @@ -114,7 +117,7 @@ public: std::shared_ptr<search::attribute::Interlock> interlock, vespalib::ISequencedTaskExecutor &attributeFieldWriter, vespalib::Executor& shared_executor, - IAttributeFactory::SP factory, + std::shared_ptr<IAttributeFactory> factory, const HwInfo &hwInfo); AttributeManager(const AttributeManager &currMgr, Spec && newSpec, @@ -151,8 +154,7 @@ public: // Implements proton::IAttributeManager - std::unique_ptr<AttributeManagerReconfig> prepare_create(Spec && spec) const override; - proton::IAttributeManager::SP create(Spec && spec) const override; + std::unique_ptr<IAttributeManagerReconfig> prepare_create(Spec&& spec) const override; std::vector<IFlushTargetSP> getFlushTargets() const override; @@ -166,7 +168,7 @@ public: void pruneRemovedFields(search::SerialNum serialNum) override; - const IAttributeFactory::SP &getFactory() const override { return _factory; } + const std::shared_ptr<IAttributeFactory> &getFactory() const override { return _factory; } vespalib::ISequencedTaskExecutor &getAttributeFieldWriter() const override; diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp index 8f57546d3c5..6f6cd01b4a4 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp +++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp @@ -77,17 +77,12 @@ FilterAttributeManager::createContext() const { throw vespalib::IllegalArgumentException("Not implemented"); } -std::unique_ptr<AttributeManagerReconfig> +std::unique_ptr<IAttributeManagerReconfig> FilterAttributeManager::prepare_create(AttributeCollectionSpec&&) const { throw vespalib::IllegalArgumentException("Not implemented"); } -IAttributeManager::SP -FilterAttributeManager::create(AttributeCollectionSpec &&) const { - throw vespalib::IllegalArgumentException("Not implemented"); -} - std::vector<searchcorespi::IFlushTarget::SP> FilterAttributeManager::getFlushTargets() const { std::vector<searchcorespi::IFlushTarget::SP> completeList = _mgr->getFlushTargets(); diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h index 4397bf81107..dff18290330 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h @@ -38,8 +38,7 @@ public: std::unique_ptr<search::attribute::AttributeReadGuard> getAttributeReadGuard(const vespalib::string &name, bool stableEnumGuard) const override; // Implements proton::IAttributeManager - std::unique_ptr<AttributeManagerReconfig> prepare_create(AttributeCollectionSpec&& spec) const override; - IAttributeManager::SP create(AttributeCollectionSpec &&) const override; + std::unique_ptr<IAttributeManagerReconfig> prepare_create(AttributeCollectionSpec&& spec) const override; std::vector<searchcorespi::IFlushTarget::SP> getFlushTargets() const override; search::SerialNum getOldestFlushedSerialNumber() const override; search::SerialNum getNewestFlushedSerialNumber() const override; diff --git a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h index 00a95607010..437e7bd0208 100644 --- a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h @@ -2,7 +2,6 @@ #pragma once -#include "attribute_collection_spec.h" #include "exclusive_attribute_read_accessor.h" #include "i_attribute_factory.h" #include <vespa/searchcommon/attribute/i_attribute_functor.h> @@ -21,7 +20,8 @@ namespace vespalib { namespace proton { -class AttributeManagerReconfig; +class AttributeCollectionSpec; +class IAttributeManagerReconfig; class ImportedAttributesRepo; /** @@ -37,13 +37,11 @@ struct IAttributeManager : public search::IAttributeManager using IAttributeFunctor = search::attribute::IAttributeFunctor; using IConstAttributeFunctor = search::attribute::IConstAttributeFunctor; - virtual std::unique_ptr<AttributeManagerReconfig> prepare_create(AttributeCollectionSpec&& spec) const = 0; - /** - * Create a new attribute manager based on the content of the current one and + * Prepare to create a new attribute manager based on the content of the current one and * the given attribute collection spec. */ - virtual IAttributeManager::SP create(AttributeCollectionSpec && spec) const = 0; + virtual std::unique_ptr<IAttributeManagerReconfig> prepare_create(AttributeCollectionSpec&& spec) const = 0; /** * Return the list of flush targets for this attribute manager. diff --git a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h new file mode 100644 index 00000000000..13080163071 --- /dev/null +++ b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h @@ -0,0 +1,22 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/searchlib/common/serialnum.h> +#include <memory> + +namespace proton { + +struct IAttributeManager; + +/** + * Interface class representing the result of the prepare step of an IAttributeManager + * reconfig. + */ +class IAttributeManagerReconfig { +public: + virtual ~IAttributeManagerReconfig() = default; + virtual std::shared_ptr<IAttributeManager> create(uint32_t docid_limit, search::SerialNum serial_num) = 0; +}; + +} diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.h b/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.h index a987d40fe6d..3f432b69277 100644 --- a/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.h +++ b/searchcore/src/vespa/searchcore/proton/docsummary/summarymanager.h @@ -2,7 +2,7 @@ #pragma once #include "isummarymanager.h" -#include <vespa/searchcore/proton/attribute/attributemanager.h> +#include <vespa/searchcore/proton/attribute/i_attribute_manager.h> #include <vespa/searchcore/proton/common/doctypename.h> #include <vespa/searchcorespi/flush/iflushtarget.h> #include <vespa/searchlib/common/tunefileinfo.h> diff --git a/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h b/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h deleted file mode 100644 index 6ca4556d666..00000000000 --- a/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include "i_attribute_writer_factory.h" -#include <vespa/searchcore/proton/attribute/attribute_writer.h> -#include <vespa/searchcore/proton/attribute/attributemanager.h> - -namespace proton { - -/** - * Factory for creating new IAttributeWriter instances during reconfig. - */ -struct AttributeWriterFactory : public IAttributeWriterFactory -{ - AttributeWriterFactory() {} - IAttributeWriter::SP create(const IAttributeWriter::SP &old, - AttributeCollectionSpec && attrSpec) const override - { - const AttributeWriter &oldAdapter = dynamic_cast<const AttributeWriter &>(*old.get()); - const proton::IAttributeManager::SP &oldMgr = oldAdapter.getAttributeManager(); - proton::IAttributeManager::SP newMgr = oldMgr->create(std::move(attrSpec)); - return std::make_shared<AttributeWriter>(newMgr); - } -}; - -} // namespace proton - diff --git a/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.cpp b/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.cpp index 60514b91aab..dd1ba597287 100644 --- a/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.cpp @@ -1,23 +1,34 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "document_subdb_reconfig.h" +#include <vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h> namespace proton { -DocumentSubDBReconfig::DocumentSubDBReconfig(std::shared_ptr<Matchers> matchers_in) +DocumentSubDBReconfig::DocumentSubDBReconfig(std::shared_ptr<Matchers> matchers_in, std::shared_ptr<IAttributeManager> attribute_manager_in) : _old_matchers(matchers_in), - _new_matchers(matchers_in) + _new_matchers(matchers_in), + _old_attribute_manager(attribute_manager_in), + _new_attribute_manager(attribute_manager_in), + _attribute_manager_reconfig() { } DocumentSubDBReconfig::~DocumentSubDBReconfig() = default; void -DocumentSubDBReconfig::complete(uint32_t docid_limit, search::SerialNum serial_num) +DocumentSubDBReconfig::set_attribute_manager_reconfig(std::unique_ptr<IAttributeManagerReconfig> attribute_manager_reconfig) { - (void) docid_limit; - (void) serial_num; + _attribute_manager_reconfig = std::move(attribute_manager_reconfig); } +void +DocumentSubDBReconfig::complete(uint32_t docid_limit, search::SerialNum serial_num) +{ + if (_attribute_manager_reconfig) { + _new_attribute_manager = _attribute_manager_reconfig->create(docid_limit, serial_num); + _attribute_manager_reconfig.reset(); + } } +} diff --git a/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.h b/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.h index 0554056100e..e2fc01aa600 100644 --- a/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.h +++ b/searchcore/src/vespa/searchcore/proton/server/document_subdb_reconfig.h @@ -6,6 +6,8 @@ namespace proton { +struct IAttributeManager; +class IAttributeManagerReconfig; class Matchers; /** @@ -15,9 +17,12 @@ class DocumentSubDBReconfig { private: std::shared_ptr<Matchers> _old_matchers; std::shared_ptr<Matchers> _new_matchers; + std::shared_ptr<IAttributeManager> _old_attribute_manager; + std::shared_ptr<IAttributeManager> _new_attribute_manager; + std::unique_ptr<IAttributeManagerReconfig> _attribute_manager_reconfig; public: - DocumentSubDBReconfig(std::shared_ptr<Matchers> matchers_in); + DocumentSubDBReconfig(std::shared_ptr<Matchers> matchers_in, std::shared_ptr<IAttributeManager> attribute_manager_in); ~DocumentSubDBReconfig(); void set_matchers(std::shared_ptr<Matchers> value) { @@ -26,7 +31,12 @@ public: bool has_matchers_changed() const noexcept { return _old_matchers != _new_matchers; } - std::shared_ptr<Matchers> matchers() const { return _new_matchers; } + std::shared_ptr<Matchers> matchers() const noexcept { return _new_matchers; } + bool has_attribute_manager_changed() const noexcept { + return _old_attribute_manager != _new_attribute_manager; + } + std::shared_ptr<IAttributeManager> attribute_manager() const noexcept { return _new_attribute_manager; } + void set_attribute_manager_reconfig(std::unique_ptr<IAttributeManagerReconfig> attribute_manager_reconfig); void complete(uint32_t docid_limit, search::SerialNum serial_num); }; diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp index eef605cea3c..1ecd2ac488a 100644 --- a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.cpp @@ -1,7 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "fast_access_doc_subdb.h" -#include "attribute_writer_factory.h" #include "document_subdb_reconfig.h" #include "emptysearchview.h" #include "fast_access_document_retriever.h" @@ -11,6 +10,7 @@ #include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h> #include <vespa/searchcore/proton/attribute/attribute_factory.h> #include <vespa/searchcore/proton/attribute/attribute_manager_initializer.h> +#include <vespa/searchcore/proton/attribute/attribute_writer.h> #include <vespa/searchcore/proton/attribute/filter_attribute_manager.h> #include <vespa/searchcore/proton/common/alloc_config.h> #include <vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.h> @@ -101,14 +101,6 @@ FastAccessDocSubDB::setupAttributeManager(AttributeManager::SP attrMgrResult) } -std::unique_ptr<AttributeCollectionSpec> -FastAccessDocSubDB::createAttributeSpec(const AttributesConfig &attrCfg, const AllocStrategy& alloc_strategy, std::optional<SerialNum> serialNum) const -{ - uint32_t docIdLimit(_dms->getCommittedDocIdLimit()); - AttributeCollectionSpecFactory factory(alloc_strategy, _fastAccessAttributesOnly); - return factory.create(attrCfg, docIdLimit, serialNum); -} - void FastAccessDocSubDB::initFeedView(IAttributeWriter::SP writer, const DocumentDBConfig &configSnapshot) { @@ -198,7 +190,6 @@ FastAccessDocSubDB::FastAccessDocSubDB(const Config &cfg, const Context &ctx) _initAttrMgr(), _fastAccessFeedView(), _configurer(_fastAccessFeedView, - std::make_unique<AttributeWriterFactory>(), getSubDbName()), _subAttributeMetrics(ctx._subAttributeMetrics), _addMetrics(cfg._addMetrics), @@ -246,7 +237,10 @@ FastAccessDocSubDB::initViews(const DocumentDBConfig &configSnapshot) std::unique_ptr<DocumentSubDBReconfig> FastAccessDocSubDB::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, const ReconfigParams& reconfig_params, std::optional<SerialNum> serial_num) { - return _configurer.prepare_reconfig(new_config_snapshot, old_config_snapshot, reconfig_params, serial_num); + auto alloc_strategy = new_config_snapshot.get_alloc_config().make_alloc_strategy(_subDbType); + AttributeCollectionSpecFactory attr_spec_factory(alloc_strategy, _fastAccessAttributesOnly); + auto docid_limit = _dms->getCommittedDocIdLimit(); + return _configurer.prepare_reconfig(new_config_snapshot, old_config_snapshot, attr_spec_factory, reconfig_params, docid_limit, serial_num); } IReprocessingTask::List @@ -267,10 +261,8 @@ FastAccessDocSubDB::applyConfig(const DocumentDBConfig &newConfigSnapshot, const params.shouldAttributeWriterChange() || newConfigSnapshot.getDocumentTypeRepoSP().get() != oldConfigSnapshot.getDocumentTypeRepoSP().get()) { proton::IAttributeManager::SP oldMgr = extractAttributeManager(_fastAccessFeedView.get()); - std::unique_ptr<AttributeCollectionSpec> attrSpec = - createAttributeSpec(newConfigSnapshot.getAttributesConfig(), alloc_strategy, serialNum); IReprocessingInitializer::UP initializer = - _configurer.reconfigure(newConfigSnapshot, oldConfigSnapshot, std::move(*attrSpec), prepared_reconfig, serialNum); + _configurer.reconfigure(newConfigSnapshot, oldConfigSnapshot, prepared_reconfig, serialNum); if (initializer->hasReprocessors()) { tasks.push_back(IReprocessingTask::SP(createReprocessingTask(*initializer, newConfigSnapshot.getDocumentTypeRepoSP()).release())); diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.h b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.h index e4c140e43e6..701c84b0dfd 100644 --- a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.h +++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb.h @@ -1,9 +1,9 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include "fast_access_doc_subdb_configurer.h" #include "storeonlydocsubdb.h" -#include <vespa/searchcore/proton/attribute/attributemanager.h> +#include "fast_access_doc_subdb_configurer.h" +#include <vespa/config-attributes.h> #include <vespa/searchcore/proton/common/docid_limit.h> #include <vespa/searchcore/proton/metrics/attribute_metrics.h> #include <vespa/searchcore/proton/metrics/metricswireservice.h> @@ -12,6 +12,8 @@ namespace search::attribute { class Interlock; } namespace proton { +class AttributeManager; + /** * The fast-access sub database keeps fast-access attribute fields in memory * in addition to the underlying document store managed by the parent class. @@ -68,7 +70,7 @@ private: const bool _hasAttributes; const bool _fastAccessAttributesOnly; - AttributeManager::SP _initAttrMgr; + std::shared_ptr<AttributeManager> _initAttrMgr; Configurer::FeedViewVarHolder _fastAccessFeedView; Configurer _configurer; AttributeMetrics &_subAttributeMetrics; @@ -78,10 +80,10 @@ private: SerialNum configSerialNum, std::shared_ptr<initializer::InitializerTask> documentMetaStoreInitTask, DocumentMetaStore::SP documentMetaStore, - std::shared_ptr<AttributeManager::SP> attrMgrResult) const; + std::shared_ptr<std::shared_ptr<AttributeManager>> attrMgrResult) const; - void setupAttributeManager(AttributeManager::SP attrMgrResult); - void initFeedView(IAttributeWriter::SP writer, const DocumentDBConfig &configSnapshot); + void setupAttributeManager(std::shared_ptr<AttributeManager> attrMgrResult); + void initFeedView(std::shared_ptr<IAttributeWriter> writer, const DocumentDBConfig &configSnapshot); protected: using Parent = StoreOnlyDocSubDB; @@ -91,14 +93,15 @@ protected: std::shared_ptr<search::attribute::Interlock> _attribute_interlock; DocIdLimit _docIdLimit; - std::unique_ptr<AttributeCollectionSpec> createAttributeSpec(const AttributesConfig &attrCfg, const AllocStrategy& alloc_strategy, std::optional<SerialNum> serialNum) const; - AttributeManager::SP getAndResetInitAttributeManager(); + std::shared_ptr<AttributeManager> getAndResetInitAttributeManager(); virtual IFlushTargetList getFlushTargetsInternal() override; void reconfigureAttributeMetrics(const IAttributeManager &newMgr, const IAttributeManager &oldMgr); IReprocessingTask::UP createReprocessingTask(IReprocessingInitializer &initializer, const std::shared_ptr<const document::DocumentTypeRepo> &docTypeRepo) const; + bool has_fast_access_attributes_only() const noexcept { return _fastAccessAttributesOnly; } + public: FastAccessDocSubDB(const Config &cfg, const Context &ctx); ~FastAccessDocSubDB(); @@ -116,7 +119,7 @@ public: applyConfig(const DocumentDBConfig &newConfigSnapshot, const DocumentDBConfig &oldConfigSnapshot, SerialNum serialNum, const ReconfigParams ¶ms, IDocumentDBReferenceResolver &resolver, const DocumentSubDBReconfig& prepared_reconfig) override; - proton::IAttributeManager::SP getAttributeManager() const override; + std::shared_ptr<IAttributeManager> getAttributeManager() const override; IDocumentRetriever::UP getDocumentRetriever() override; void onReplayDone() override; void onReprocessDone(SerialNum serialNum) override; diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.cpp b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.cpp index 0a88b591f9f..af1cc170c31 100644 --- a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.cpp @@ -1,10 +1,14 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "fast_access_doc_subdb_configurer.h" +#include "fast_access_feed_view.h" #include "document_subdb_reconfig.h" -#include "i_attribute_writer_factory.h" #include "documentdbconfig.h" +#include "reconfig_params.h" +#include <vespa/searchcore/proton/attribute/attribute_collection_spec.h> +#include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> +#include <vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h> #include <vespa/searchcore/proton/common/document_type_inspector.h> #include <vespa/searchcore/proton/common/indexschema_inspector.h> #include <vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.h> @@ -18,9 +22,9 @@ using ARIConfig = AttributeReprocessingInitializer::Config; void FastAccessDocSubDBConfigurer::reconfigureFeedView(FastAccessFeedView & curr, - Schema::SP schema, + std::shared_ptr<Schema> schema, std::shared_ptr<const DocumentTypeRepo> repo, - IAttributeWriter::SP writer) + std::shared_ptr<IAttributeWriter> writer) { _feedView.set(std::make_shared<FastAccessFeedView>( StoreOnlyFeedView::Context(curr.getSummaryAdapter(), @@ -35,10 +39,8 @@ FastAccessDocSubDBConfigurer::reconfigureFeedView(FastAccessFeedView & curr, } FastAccessDocSubDBConfigurer::FastAccessDocSubDBConfigurer(FeedViewVarHolder &feedView, - IAttributeWriterFactory::UP factory, const vespalib::string &subDbName) : _feedView(feedView), - _factory(std::move(factory)), _subDbName(subDbName) { } @@ -46,27 +48,34 @@ FastAccessDocSubDBConfigurer::FastAccessDocSubDBConfigurer(FeedViewVarHolder &fe FastAccessDocSubDBConfigurer::~FastAccessDocSubDBConfigurer() = default; std::unique_ptr<DocumentSubDBReconfig> -FastAccessDocSubDBConfigurer::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, const ReconfigParams& reconfig_params, std::optional<search::SerialNum> serial_num) +FastAccessDocSubDBConfigurer::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, + const DocumentDBConfig& old_config_snapshot, + const AttributeCollectionSpecFactory& attr_spec_factory, + const ReconfigParams& reconfig_params, + uint32_t docid_limit, + std::optional<search::SerialNum> serial_num) { (void) new_config_snapshot; (void) old_config_snapshot; - (void) reconfig_params; (void) serial_num; - return std::make_unique<DocumentSubDBReconfig>(std::shared_ptr<Matchers>()); + auto old_attribute_writer = _feedView.get()->getAttributeWriter(); + auto old_attribute_manager = old_attribute_writer->getAttributeManager(); + auto reconfig = std::make_unique<DocumentSubDBReconfig>(std::shared_ptr<Matchers>(), old_attribute_manager); + if (reconfig_params.shouldAttributeManagerChange()) { + auto attr_spec = attr_spec_factory.create(new_config_snapshot.getAttributesConfig(), docid_limit, serial_num); + reconfig->set_attribute_manager_reconfig(old_attribute_manager->prepare_create(std::move(*attr_spec))); + } + return reconfig; } IReprocessingInitializer::UP FastAccessDocSubDBConfigurer::reconfigure(const DocumentDBConfig &newConfig, const DocumentDBConfig &oldConfig, - AttributeCollectionSpec && attrSpec, const DocumentSubDBReconfig& prepared_reconfig, search::SerialNum serial_num) { - (void) prepared_reconfig; - FastAccessFeedView::SP oldView = _feedView.get(); - auto& attr_spec_serial_num = attrSpec.getCurrentSerialNum(); - assert(!attr_spec_serial_num.has_value() || attr_spec_serial_num.value() == serial_num); - IAttributeWriter::SP writer = _factory->create(oldView->getAttributeWriter(), std::move(attrSpec)); + std::shared_ptr<FastAccessFeedView> oldView = _feedView.get(); + auto writer = std::make_shared<AttributeWriter>(prepared_reconfig.attribute_manager()); reconfigureFeedView(*oldView, newConfig.getSchemaSP(), newConfig.getDocumentTypeRepoSP(), writer); const document::DocumentType *newDocType = newConfig.getDocumentType(); diff --git a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.h b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.h index 7a50aa35c81..91405fb7117 100644 --- a/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.h +++ b/searchcore/src/vespa/searchcore/proton/server/fast_access_doc_subdb_configurer.h @@ -1,13 +1,26 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + #pragma once -#include "searchable_doc_subdb_configurer.h" -#include "fast_access_feed_view.h" -#include "i_attribute_writer_factory.h" -#include <vespa/searchcore/proton/reprocessing/i_reprocessing_initializer.h> +#include <vespa/searchlib/common/serialnum.h> +#include <vespa/vespalib/stllike/string.h> +#include <vespa/vespalib/util/varholder.h> +#include <memory> +#include <optional> + +namespace document { class DocumentTypeRepo; } +namespace search::index { class Schema; } namespace proton { +class AttributeCollectionSpecFactory; +class DocumentDBConfig; +class DocumentSubDBReconfig; +class FastAccessFeedView; +class IAttributeWriter; +struct IReprocessingInitializer; +class ReconfigParams; + /** * Class used to reconfig the feed view used in a fast-access sub database * when the set of fast-access attributes change. @@ -15,31 +28,35 @@ namespace proton { class FastAccessDocSubDBConfigurer { public: - using FeedViewVarHolder = vespalib::VarHolder<FastAccessFeedView::SP>; + using FeedViewVarHolder = vespalib::VarHolder<std::shared_ptr<FastAccessFeedView>>; private: FeedViewVarHolder &_feedView; - IAttributeWriterFactory::UP _factory; vespalib::string _subDbName; void reconfigureFeedView(FastAccessFeedView & curr, - search::index::Schema::SP schema, + std::shared_ptr<search::index::Schema> schema, std::shared_ptr<const document::DocumentTypeRepo> repo, - IAttributeWriter::SP attrWriter); + std::shared_ptr<IAttributeWriter> attrWriter); public: FastAccessDocSubDBConfigurer(FeedViewVarHolder &feedView, - IAttributeWriterFactory::UP factory, const vespalib::string &subDbName); ~FastAccessDocSubDBConfigurer(); - std::unique_ptr<DocumentSubDBReconfig> prepare_reconfig(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, const ReconfigParams& reconfig_params, std::optional<search::SerialNum> serial_num); - - IReprocessingInitializer::UP reconfigure(const DocumentDBConfig &newConfig, - const DocumentDBConfig &oldConfig, - AttributeCollectionSpec && attrSpec, - const DocumentSubDBReconfig& prepared_reconfig, - search::SerialNum serial_num); + std::unique_ptr<DocumentSubDBReconfig> + prepare_reconfig(const DocumentDBConfig& new_config_snapshot, + const DocumentDBConfig& old_config_snapshot, + const AttributeCollectionSpecFactory& attr_spec_factory, + const ReconfigParams& reconfig_params, + uint32_t docid_limit, + std::optional<search::SerialNum> serial_num); + + std::unique_ptr<IReprocessingInitializer> + reconfigure(const DocumentDBConfig &newConfig, + const DocumentDBConfig &oldConfig, + const DocumentSubDBReconfig& prepared_reconfig, + search::SerialNum serial_num); }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/server/i_attribute_writer_factory.h b/searchcore/src/vespa/searchcore/proton/server/i_attribute_writer_factory.h deleted file mode 100644 index 7662d1cb164..00000000000 --- a/searchcore/src/vespa/searchcore/proton/server/i_attribute_writer_factory.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include <vespa/searchcore/proton/attribute/attribute_collection_spec.h> -#include <vespa/searchcore/proton/attribute/i_attribute_writer.h> - -namespace proton { - -/** - * Interface for a factory for creating new IAttributeWriter instances during reconfig. - */ -struct IAttributeWriterFactory -{ - using UP = std::unique_ptr<IAttributeWriterFactory>; - virtual ~IAttributeWriterFactory() = default; - virtual IAttributeWriter::SP create(const IAttributeWriter::SP &old, - AttributeCollectionSpec && attrSpec) const = 0; -}; - -} // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp index 532c2e868b6..f865d533d85 100644 --- a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp @@ -2,6 +2,7 @@ #include "matchview.h" #include "searchcontext.h" +#include <vespa/searchcore/proton/attribute/i_attribute_manager.h> #include <vespa/searchcore/proton/matching/matcher.h> #include <vespa/searchlib/engine/searchrequest.h> #include <vespa/searchlib/engine/searchreply.h> @@ -34,8 +35,8 @@ using matching::Matcher; using matching::SessionManager; MatchView::MatchView(Matchers::SP matchers, - IndexSearchable::SP indexSearchable, - IAttributeManager::SP attrMgr, + std::shared_ptr<IndexSearchable> indexSearchable, + std::shared_ptr<IAttributeManager> attrMgr, SessionManager & sessionMgr, IDocumentMetaStoreContext::SP metaStore, DocIdLimit &docIdLimit) diff --git a/searchcore/src/vespa/searchcore/proton/server/matchview.h b/searchcore/src/vespa/searchcore/proton/server/matchview.h index 2a4347377df..20db5665832 100644 --- a/searchcore/src/vespa/searchcore/proton/server/matchview.h +++ b/searchcore/src/vespa/searchcore/proton/server/matchview.h @@ -3,27 +3,32 @@ #pragma once #include "matchers.h" -#include <vespa/searchcore/proton/attribute/attributemanager.h> #include <vespa/searchcore/proton/common/docid_limit.h> -#include <vespa/searchcore/proton/documentmetastore/documentmetastorecontext.h> +#include <vespa/searchcore/proton/documentmetastore/i_document_meta_store_context.h> #include <vespa/searchcore/proton/matching/match_context.h> #include <vespa/searchcore/proton/summaryengine/isearchhandler.h> -#include <vespa/searchcorespi/index/indexsearchable.h> + +namespace searchcorespi { class IndexSearchable; } namespace proton { namespace matching { - class SessionManager; - class Matcher; + +class MatchContext; +class Matcher; +class SessionManager; + } +struct IAttributeManager; + class MatchView { using SessionManager = matching::SessionManager; - Matchers::SP _matchers; - searchcorespi::IndexSearchable::SP _indexSearchable; - IAttributeManager::SP _attrMgr; + std::shared_ptr<Matchers> _matchers; + std::shared_ptr<searchcorespi::IndexSearchable> _indexSearchable; + std::shared_ptr<IAttributeManager> _attrMgr; SessionManager & _sessionMgr; - IDocumentMetaStoreContext::SP _metaStore; + std::shared_ptr<IDocumentMetaStoreContext> _metaStore; DocIdLimit &_docIdLimit; size_t getNumDocs() const { @@ -35,20 +40,20 @@ public: MatchView(const MatchView &) = delete; MatchView & operator = (const MatchView &) = delete; - MatchView(Matchers::SP matchers, - searchcorespi::IndexSearchable::SP indexSearchable, - IAttributeManager::SP attrMgr, + MatchView(std::shared_ptr<Matchers> matchers, + std::shared_ptr<searchcorespi::IndexSearchable> indexSearchable, + std::shared_ptr<IAttributeManager> attrMgr, SessionManager & sessionMgr, - IDocumentMetaStoreContext::SP metaStore, + std::shared_ptr<IDocumentMetaStoreContext> metaStore, DocIdLimit &docIdLimit); ~MatchView(); - const Matchers::SP & getMatchers() const { return _matchers; } - const searchcorespi::IndexSearchable::SP & getIndexSearchable() const { return _indexSearchable; } - const IAttributeManager::SP & getAttributeManager() const { return _attrMgr; } - SessionManager & getSessionManager() const { return _sessionMgr; } - const IDocumentMetaStoreContext::SP & getDocumentMetaStore() const { return _metaStore; } - DocIdLimit & getDocIdLimit() const { return _docIdLimit; } + const std::shared_ptr<Matchers>& getMatchers() const noexcept { return _matchers; } + const std::shared_ptr<searchcorespi::IndexSearchable>& getIndexSearchable() const noexcept { return _indexSearchable; } + const std::shared_ptr<IAttributeManager>& getAttributeManager() const noexcept { return _attrMgr; } + SessionManager & getSessionManager() const noexcept { return _sessionMgr; } + const std::shared_ptr<IDocumentMetaStoreContext>& getDocumentMetaStore() const noexcept { return _metaStore; } + DocIdLimit & getDocIdLimit() const noexcept { return _docIdLimit; } // Throws on error. std::shared_ptr<matching::Matcher> getMatcher(const vespalib::string & rankProfile) const; @@ -58,7 +63,7 @@ public: return _matchers->getStats(rankProfile); } - matching::MatchContext::UP createContext() const; + std::unique_ptr<matching::MatchContext> createContext() const; std::unique_ptr<search::engine::SearchReply> match(std::shared_ptr<const ISearchHandler> searchHandler, diff --git a/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp b/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp index fa4340f7659..3ffd610221b 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.cpp @@ -3,8 +3,14 @@ #include "searchable_doc_subdb_configurer.h" #include "document_subdb_reconfig.h" #include "reconfig_params.h" +#include "searchable_feed_view.h" +#include "searchview.h" +#include <vespa/config-rank-profiles.h> #include <vespa/searchcore/proton/matching/matcher.h> +#include <vespa/searchcore/proton/attribute/attribute_collection_spec.h> +#include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> +#include <vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h> #include <vespa/searchcore/proton/attribute/imported_attributes_repo.h> #include <vespa/searchcore/proton/common/document_type_inspector.h> #include <vespa/searchcore/proton/common/indexschema_inspector.h> @@ -28,11 +34,11 @@ using matching::OnnxModels; using ARIConfig = AttributeReprocessingInitializer::Config; void -SearchableDocSubDBConfigurer::reconfigureFeedView(IAttributeWriter::SP attrWriter, - Schema::SP schema, +SearchableDocSubDBConfigurer::reconfigureFeedView(std::shared_ptr<IAttributeWriter> attrWriter, + std::shared_ptr<Schema> schema, std::shared_ptr<const DocumentTypeRepo> repo) { - SearchableFeedView::SP curr = _feedView.get(); + auto curr = _feedView.get(); _feedView.set(std::make_shared<SearchableFeedView>( StoreOnlyFeedView::Context(curr->getSummaryAdapter(), std::move(schema), @@ -48,9 +54,9 @@ SearchableDocSubDBConfigurer::reconfigureFeedView(IAttributeWriter::SP attrWrite void SearchableDocSubDBConfigurer:: -reconfigureMatchView(const IndexSearchable::SP &indexSearchable) +reconfigureMatchView(const std::shared_ptr<IndexSearchable>& indexSearchable) { - SearchView::SP curr = _searchView.get(); + auto curr = _searchView.get(); reconfigureMatchView(curr->getMatchers(), indexSearchable, curr->getAttributeManager()); @@ -58,20 +64,20 @@ reconfigureMatchView(const IndexSearchable::SP &indexSearchable) void SearchableDocSubDBConfigurer:: -reconfigureMatchView(const Matchers::SP &matchers, - const IndexSearchable::SP &indexSearchable, - const IAttributeManager::SP &attrMgr) +reconfigureMatchView(const std::shared_ptr<Matchers>& matchers, + const std::shared_ptr<IndexSearchable>& indexSearchable, + const std::shared_ptr<IAttributeManager>& attrMgr) { - SearchView::SP curr = _searchView.get(); + auto curr = _searchView.get(); auto matchView = std::make_shared<MatchView>(matchers, indexSearchable, attrMgr, curr->getSessionManager(), curr->getDocumentMetaStore(), curr->getDocIdLimit()); reconfigureSearchView(matchView); } void -SearchableDocSubDBConfigurer::reconfigureSearchView(MatchView::SP matchView) +SearchableDocSubDBConfigurer::reconfigureSearchView(std::shared_ptr<MatchView> matchView) { - SearchView::SP curr = _searchView.get(); + auto curr = _searchView.get(); // make sure the initial search does not spend time waiting for // expression compilation completion during rank program setup. vespalib::eval::CompileCache::wait_pending(); @@ -79,14 +85,14 @@ SearchableDocSubDBConfigurer::reconfigureSearchView(MatchView::SP matchView) } void -SearchableDocSubDBConfigurer::reconfigureSearchView(ISummaryManager::ISummarySetup::SP summarySetup, - MatchView::SP matchView) +SearchableDocSubDBConfigurer::reconfigureSearchView(std::shared_ptr<ISummaryManager::ISummarySetup> summarySetup, + std::shared_ptr<MatchView> matchView) { _searchView.set(SearchView::create(std::move(summarySetup), std::move(matchView))); } SearchableDocSubDBConfigurer:: -SearchableDocSubDBConfigurer(const ISummaryManager::SP &summaryMgr, +SearchableDocSubDBConfigurer(const std::shared_ptr<ISummaryManager>& summaryMgr, SearchViewHolder &searchView, FeedViewHolder &feedView, matching::QueryLimiter &queryLimiter, @@ -134,46 +140,42 @@ SearchableDocSubDBConfigurer::createMatchers(const DocumentDBConfig& new_config_ void SearchableDocSubDBConfigurer::reconfigureIndexSearchable() { - SearchableFeedView::SP feedView(_feedView.get()); - const IIndexWriter::SP &indexWriter = feedView->getIndexWriter(); - const searchcorespi::IIndexManager::SP &indexManager = indexWriter->getIndexManager(); + auto feedView(_feedView.get()); + auto& indexWriter = feedView->getIndexWriter(); + auto& indexManager = indexWriter->getIndexManager(); reconfigureMatchView(indexManager->getSearchable()); } std::unique_ptr<DocumentSubDBReconfig> -SearchableDocSubDBConfigurer::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, const ReconfigParams& reconfig_params, std::optional<search::SerialNum> serial_num) +SearchableDocSubDBConfigurer::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, + const DocumentDBConfig& old_config_snapshot, + const AttributeCollectionSpecFactory& attr_spec_factory, + const ReconfigParams& reconfig_params, + uint32_t docid_limit, + std::optional<search::SerialNum> serial_num) { (void) old_config_snapshot; (void) serial_num; auto old_matchers = _searchView.get()->getMatchers(); - auto reconfig = std::make_unique<DocumentSubDBReconfig>(std::move(old_matchers)); + auto old_attribute_manager = _searchView.get()->getAttributeManager(); + auto reconfig = std::make_unique<DocumentSubDBReconfig>(std::move(old_matchers), old_attribute_manager); if (reconfig_params.shouldMatchersChange()) { reconfig->set_matchers(createMatchers(new_config_snapshot)); } + if (reconfig_params.shouldAttributeManagerChange()) { + auto attr_spec = attr_spec_factory.create(new_config_snapshot.getAttributesConfig(), docid_limit, serial_num); + reconfig->set_attribute_manager_reconfig(old_attribute_manager->prepare_create(std::move(*attr_spec))); + } return reconfig; } -void -SearchableDocSubDBConfigurer:: -reconfigure(const DocumentDBConfig &newConfig, - const DocumentDBConfig &oldConfig, - const ReconfigParams ¶ms, - IDocumentDBReferenceResolver &resolver, - const DocumentSubDBReconfig& prepared_reconfig, - search::SerialNum serial_num) -{ - assert(!params.shouldAttributeManagerChange()); - AttributeCollectionSpec attrSpec(AttributeCollectionSpec::AttributeList(), 0, 0); - reconfigure(newConfig, oldConfig, std::move(attrSpec), params, resolver, prepared_reconfig, serial_num); -} - namespace { IReprocessingInitializer::UP createAttributeReprocessingInitializer(const DocumentDBConfig &newConfig, - const IAttributeManager::SP &newAttrMgr, + const std::shared_ptr<IAttributeManager>& newAttrMgr, const DocumentDBConfig &oldConfig, - const IAttributeManager::SP &oldAttrMgr, + const std::shared_ptr<IAttributeManager>& oldAttrMgr, const vespalib::string &subDbName, search::SerialNum serialNum) { @@ -194,7 +196,6 @@ createAttributeReprocessingInitializer(const DocumentDBConfig &newConfig, IReprocessingInitializer::UP SearchableDocSubDBConfigurer::reconfigure(const DocumentDBConfig &newConfig, const DocumentDBConfig &oldConfig, - AttributeCollectionSpec && attrSpec, const ReconfigParams ¶ms, IDocumentDBReferenceResolver &resolver, const DocumentSubDBReconfig& prepared_reconfig, @@ -203,19 +204,17 @@ SearchableDocSubDBConfigurer::reconfigure(const DocumentDBConfig &newConfig, bool shouldMatchViewChange = prepared_reconfig.has_matchers_changed(); bool shouldSearchViewChange = false; bool shouldFeedViewChange = params.shouldSchemaChange(); - SearchView::SP searchView = _searchView.get(); + auto searchView = _searchView.get(); auto matchers = prepared_reconfig.matchers(); IReprocessingInitializer::UP initializer; - IAttributeManager::SP attrMgr = searchView->getAttributeManager(); - IAttributeWriter::SP attrWriter = _feedView.get()->getAttributeWriter(); - if (params.shouldAttributeManagerChange()) { - auto attr_spec_serial_num = attrSpec.getCurrentSerialNum(); - assert(!attr_spec_serial_num.has_value() || attr_spec_serial_num.value() == serial_num); - IAttributeManager::SP newAttrMgr = attrMgr->create(std::move(attrSpec)); + auto attrMgr = searchView->getAttributeManager(); + auto attrWriter = _feedView.get()->getAttributeWriter(); + if (prepared_reconfig.has_attribute_manager_changed()) { + auto newAttrMgr = prepared_reconfig.attribute_manager(); newAttrMgr->setImportedAttributes(resolver.resolve(*newAttrMgr, *attrMgr, searchView->getDocumentMetaStore(), newConfig.getMaintenanceConfigSP()->getVisibilityDelay())); - IAttributeManager::SP oldAttrMgr = attrMgr; + auto oldAttrMgr = attrMgr; attrMgr = newAttrMgr; shouldMatchViewChange = true; @@ -229,12 +228,12 @@ SearchableDocSubDBConfigurer::reconfigure(const DocumentDBConfig &newConfig, shouldFeedViewChange = true; } - ISummaryManager::ISummarySetup::SP sumSetup = _searchView.get()->getSummarySetup(); + auto sumSetup = _searchView.get()->getSummarySetup(); if (params.shouldSummaryManagerChange() || params.shouldAttributeManagerChange()) { - ISummaryManager::SP sumMgr(_summaryMgr); - ISummaryManager::ISummarySetup::SP newSumSetup = + auto sumMgr(_summaryMgr); + auto newSumSetup = sumMgr->createSummarySetup(newConfig.getSummaryConfig(), newConfig.getJuniperrcConfig(), newConfig.getDocumentTypeRepoSP(), @@ -245,7 +244,7 @@ SearchableDocSubDBConfigurer::reconfigure(const DocumentDBConfig &newConfig, } if (shouldMatchViewChange) { - IndexSearchable::SP indexSearchable = searchView->getIndexSearchable(); + auto indexSearchable = searchView->getIndexSearchable(); reconfigureMatchView(matchers, indexSearchable, attrMgr); searchView = _searchView.get(); } diff --git a/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.h b/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.h index e6b0ebda7c1..7cb9085f7a1 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.h +++ b/searchcore/src/vespa/searchcore/proton/server/searchable_doc_subdb_configurer.h @@ -2,33 +2,35 @@ #pragma once -#include "isummaryadapter.h" -#include "matchers.h" -#include "matchview.h" -#include "searchable_feed_view.h" -#include "searchview.h" -#include <vespa/searchcore/proton/attribute/i_attribute_writer.h> #include <vespa/searchcore/proton/docsummary/summarymanager.h> -#include <vespa/searchcore/proton/index/i_index_writer.h> -#include <vespa/searchcore/proton/reprocessing/i_reprocessing_initializer.h> -#include <vespa/searchsummary/config/config-juniperrc.h> -#include <vespa/searchcommon/common/schema.h> -#include <vespa/config-attributes.h> -#include <vespa/config-indexschema.h> -#include <vespa/config-rank-profiles.h> -#include <vespa/config-summary.h> #include <vespa/vespalib/util/varholder.h> -#include <vespa/searchcore/proton/reference/i_document_db_reference_resolver.h> + +namespace searchcorespi { class IndexSearchable; } namespace proton::matching { - class RankingExpressions; - class OnnxModels; + +class RankingExpressions; +class OnnxModels; +class QueryLimiter; + } + +namespace vespalib::eval { struct ConstantValueFactory; } +namespace vespalib { class Clock; } + namespace proton { +class AttributeCollectionSpecFactory; +class DocumentDBConfig; class DocumentSubDBReconfig; +class IAttributeWriter; struct IDocumentDBReferenceResolver; +struct IReprocessingInitializer; +class MatchView; +class Matchers; class ReconfigParams; +class SearchView; +class SearchableFeedView; /** * Class used to reconfig the feed view and search view used in a searchable sub database. @@ -36,9 +38,9 @@ class ReconfigParams; class SearchableDocSubDBConfigurer { private: - using SearchViewHolder = vespalib::VarHolder<SearchView::SP>; - using FeedViewHolder = vespalib::VarHolder<SearchableFeedView::SP>; - const ISummaryManager::SP &_summaryMgr; + using SearchViewHolder = vespalib::VarHolder<std::shared_ptr<SearchView>>; + using FeedViewHolder = vespalib::VarHolder<std::shared_ptr<SearchableFeedView>>; + const std::shared_ptr<ISummaryManager>& _summaryMgr; SearchViewHolder &_searchView; FeedViewHolder &_feedView; matching::QueryLimiter &_queryLimiter; @@ -47,24 +49,24 @@ private: vespalib::string _subDbName; uint32_t _distributionKey; - void reconfigureFeedView(IAttributeWriter::SP attrWriter, - search::index::Schema::SP schema, + void reconfigureFeedView(std::shared_ptr<IAttributeWriter> attrWriter, + std::shared_ptr<search::index::Schema> schema, std::shared_ptr<const document::DocumentTypeRepo> repo); - void reconfigureMatchView(const searchcorespi::IndexSearchable::SP &indexSearchable); + void reconfigureMatchView(const std::shared_ptr<searchcorespi::IndexSearchable>& indexSearchable); - void reconfigureMatchView(const Matchers::SP &matchers, - const searchcorespi::IndexSearchable::SP &indexSearchable, - const IAttributeManager::SP &attrMgr); + void reconfigureMatchView(const std::shared_ptr<Matchers>& matchers, + const std::shared_ptr<searchcorespi::IndexSearchable>& indexSearchable, + const std::shared_ptr<IAttributeManager>& attrMgr); - void reconfigureSearchView(MatchView::SP matchView); + void reconfigureSearchView(std::shared_ptr<MatchView> matchView); - void reconfigureSearchView(ISummaryManager::ISummarySetup::SP summarySetup, MatchView::SP matchView); + void reconfigureSearchView(std::shared_ptr<ISummaryManager::ISummarySetup> summarySetup, std::shared_ptr<MatchView> matchView); public: SearchableDocSubDBConfigurer(const SearchableDocSubDBConfigurer &) = delete; SearchableDocSubDBConfigurer & operator = (const SearchableDocSubDBConfigurer &) = delete; - SearchableDocSubDBConfigurer(const ISummaryManager::SP &summaryMgr, + SearchableDocSubDBConfigurer(const std::shared_ptr<ISummaryManager>& summaryMgr, SearchViewHolder &searchView, FeedViewHolder &feedView, matching::QueryLimiter &queryLimiter, @@ -74,23 +76,21 @@ public: uint32_t distributionKey); ~SearchableDocSubDBConfigurer(); - Matchers::SP createMatchers(const DocumentDBConfig& new_config_snapshot); + std::shared_ptr<Matchers> createMatchers(const DocumentDBConfig& new_config_snapshot); void reconfigureIndexSearchable(); - std::unique_ptr<DocumentSubDBReconfig> prepare_reconfig(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, const ReconfigParams& reconfig_params, std::optional<search::SerialNum> serial_num); - - void reconfigure(const DocumentDBConfig &newConfig, - const DocumentDBConfig &oldConfig, - const ReconfigParams ¶ms, - IDocumentDBReferenceResolver &resolver, - const DocumentSubDBReconfig& prepared_reconfig, - search::SerialNum serial_num); + std::unique_ptr<DocumentSubDBReconfig> + prepare_reconfig(const DocumentDBConfig& new_config_snapshot, + const DocumentDBConfig& old_config_snapshot, + const AttributeCollectionSpecFactory& attr_spec_factory, + const ReconfigParams& reconfig_params, + uint32_t docid_limit, + std::optional<search::SerialNum> serial_num); - IReprocessingInitializer::UP + std::unique_ptr<IReprocessingInitializer> reconfigure(const DocumentDBConfig &newConfig, const DocumentDBConfig &oldConfig, - AttributeCollectionSpec && attrSpec, const ReconfigParams ¶ms, IDocumentDBReferenceResolver &resolver, const DocumentSubDBReconfig& prepared_reconfig, diff --git a/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp b/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp index 187be079d03..04ff21d13d5 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.cpp @@ -6,6 +6,7 @@ #include "document_subdb_reconfig.h" #include "reconfig_params.h" #include "i_document_subdb_owner.h" +#include <vespa/searchcore/proton/attribute/attribute_collection_spec_factory.h> #include <vespa/searchcore/proton/attribute/attribute_writer.h> #include <vespa/searchcore/proton/common/alloc_config.h> #include <vespa/searchcore/proton/flushengine/threadedflushtarget.h> @@ -13,6 +14,8 @@ #include <vespa/searchcore/proton/index/index_writer.h> #include <vespa/searchcore/proton/reference/document_db_reference.h> #include <vespa/searchcore/proton/reference/gid_to_lid_change_handler.h> +#include <vespa/searchcore/proton/reference/i_document_db_reference_resolver.h> +#include <vespa/searchcore/proton/reprocessing/i_reprocessing_initializer.h> #include <vespa/searchlib/fef/indexproperties.h> #include <vespa/searchlib/fef/properties.h> #include <vespa/eval/eval/fast_value.h> @@ -135,7 +138,10 @@ reconfigureMatchingMetrics(const RankProfilesConfig &cfg) std::unique_ptr<DocumentSubDBReconfig> SearchableDocSubDB::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, const DocumentDBConfig& old_config_snapshot, const ReconfigParams& reconfig_params, std::optional<SerialNum> serial_num) { - return _configurer.prepare_reconfig(new_config_snapshot, old_config_snapshot, reconfig_params, serial_num); + auto alloc_strategy = new_config_snapshot.get_alloc_config().make_alloc_strategy(_subDbType); + AttributeCollectionSpecFactory attr_spec_factory(alloc_strategy, has_fast_access_attributes_only()); + auto docid_limit = _dms->getCommittedDocIdLimit(); + return _configurer.prepare_reconfig(new_config_snapshot, old_config_snapshot, attr_spec_factory, reconfig_params, docid_limit, serial_num); } IReprocessingTask::List @@ -146,15 +152,13 @@ SearchableDocSubDB::applyConfig(const DocumentDBConfig &newConfigSnapshot, const StoreOnlyDocSubDB::reconfigure(newConfigSnapshot.getStoreConfig(), alloc_strategy); IReprocessingTask::List tasks; applyFlushConfig(newConfigSnapshot.getMaintenanceConfigSP()->getFlushConfig()); - if (params.shouldMatchersChange() && _addMetrics) { + if (prepared_reconfig.has_matchers_changed() && _addMetrics) { reconfigureMatchingMetrics(newConfigSnapshot.getRankProfilesConfig()); } - if (params.shouldAttributeManagerChange()) { + if (prepared_reconfig.has_attribute_manager_changed()) { proton::IAttributeManager::SP oldMgr = getAttributeManager(); - std::unique_ptr<AttributeCollectionSpec> attrSpec = - createAttributeSpec(newConfigSnapshot.getAttributesConfig(), alloc_strategy, serialNum); IReprocessingInitializer::UP initializer = - _configurer.reconfigure(newConfigSnapshot, oldConfigSnapshot, std::move(*attrSpec), params, resolver, prepared_reconfig, serialNum); + _configurer.reconfigure(newConfigSnapshot, oldConfigSnapshot, params, resolver, prepared_reconfig, serialNum); if (initializer && initializer->hasReprocessors()) { tasks.emplace_back(createReprocessingTask(*initializer, newConfigSnapshot.getDocumentTypeRepoSP())); } diff --git a/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.h b/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.h index 522ccd69b2a..45a9f1a27b1 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.h +++ b/searchcore/src/vespa/searchcore/proton/server/searchabledocsubdb.h @@ -8,9 +8,9 @@ #include "summaryadapter.h" #include "igetserialnum.h" #include "document_db_flush_config.h" +#include <vespa/config-rank-profiles.h> #include <vespa/eval/eval/value_cache/constant_tensor_loader.h> #include <vespa/eval/eval/value_cache/constant_value_cache.h> -#include <vespa/searchcore/proton/attribute/attributemanager.h> #include <vespa/searchcore/proton/common/doctypename.h> #include <vespa/searchcore/proton/docsummary/summarymanager.h> #include <vespa/searchcore/proton/documentmetastore/documentmetastorecontext.h> @@ -109,11 +109,11 @@ public: void clearViews() override; - proton::IAttributeManager::SP getAttributeManager() const override { + std::shared_ptr<IAttributeManager> getAttributeManager() const override { return _rSearchView.get()->getAttributeManager(); } - const searchcorespi::IIndexManager::SP &getIndexManager() const override { + const std::shared_ptr<searchcorespi::IIndexManager>& getIndexManager() const override { return _indexMgr; } diff --git a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp index 7a909bbebd8..0c96b43a727 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp @@ -3,6 +3,7 @@ #include "searchview.h" #include <vespa/searchcore/proton/docsummary/docsumcontext.h> #include <vespa/searchlib/engine/searchreply.h> +#include <vespa/searchlib/queryeval/begin_and_end_id.h> #include <vespa/vespalib/data/slime/slime.h> #include <vespa/vespalib/util/issue.h> @@ -77,7 +78,7 @@ hasAnyLidsMoved(const DocsumRequest & request, /** * Create empty docsum reply **/ -DocsumReply::UP +std::unique_ptr<DocsumReply> createEmptyReply(const DocsumRequest &) { return std::make_unique<DocsumReply>(); @@ -86,10 +87,10 @@ createEmptyReply(const DocsumRequest &) } std::shared_ptr<SearchView> -SearchView::create(ISummaryManager::ISummarySetup::SP summarySetup, MatchView::SP matchView) { +SearchView::create(std::shared_ptr<ISummaryManager::ISummarySetup> summarySetup, std::shared_ptr<MatchView> matchView) { return std::shared_ptr<SearchView>( new SearchView(std::move(summarySetup), std::move(matchView))); } -SearchView::SearchView(ISummaryManager::ISummarySetup::SP summarySetup, MatchView::SP matchView) +SearchView::SearchView(std::shared_ptr<ISummaryManager::ISummarySetup> summarySetup, std::shared_ptr<MatchView> matchView) : ISearchHandler(), _summarySetup(std::move(summarySetup)), _matchView(std::move(matchView)) @@ -97,7 +98,7 @@ SearchView::SearchView(ISummaryManager::ISummarySetup::SP summarySetup, MatchVie SearchView::~SearchView() = default; -DocsumReply::UP +std::unique_ptr<DocsumReply> SearchView::getDocsums(const DocsumRequest & req) { LOG(spam, "getDocsums(): resultClass(%s), numHits(%zu)", req.resultClassName.c_str(), req.hits.size()); @@ -117,14 +118,14 @@ SearchView::getDocsums(const DocsumRequest & req) SearchView::InternalDocsumReply SearchView::getDocsumsInternal(const DocsumRequest & req) { - IDocumentMetaStoreContext::IReadGuard::UP readGuard = _matchView->getDocumentMetaStore()->getReadGuard(); + auto readGuard = _matchView->getDocumentMetaStore()->getReadGuard(); const search::IDocumentMetaStore & metaStore = readGuard->get(); uint32_t numUsedLids = metaStore.getNumUsedLids(); uint64_t startGeneration = readGuard->get().getCurrentGeneration(); convertGidsToLids(req, metaStore, _matchView->getDocIdLimit().get()); - IDocsumStore::UP store(_summarySetup->createDocsumStore()); - MatchContext::UP mctx = _matchView->createContext(); + auto store(_summarySetup->createDocsumStore()); + auto mctx = _matchView->createContext(); auto ctx = std::make_unique<DocsumContext>(req, _summarySetup->getDocsumWriter(), *store, _matchView->getMatcher(req.ranking), mctx->getSearchContext(), mctx->getAttributeContext(), *_summarySetup->getAttributeManager(), getSessionManager()); diff --git a/searchcore/src/vespa/searchcore/proton/server/searchview.h b/searchcore/src/vespa/searchcore/proton/server/searchview.h index f27052cace1..f2c88963c83 100644 --- a/searchcore/src/vespa/searchcore/proton/server/searchview.h +++ b/searchcore/src/vespa/searchcore/proton/server/searchview.h @@ -16,30 +16,30 @@ public: using InternalDocsumReply = std::pair<std::unique_ptr<DocsumReply>, bool>; using SP = std::shared_ptr<SearchView>; - static std::shared_ptr<SearchView> create(ISummaryManager::ISummarySetup::SP summarySetup, MatchView::SP matchView); + static std::shared_ptr<SearchView> create(std::shared_ptr<ISummaryManager::ISummarySetup> summarySetup, std::shared_ptr<MatchView> matchView); SearchView(const SearchView &) = delete; SearchView(SearchView &&) = delete; SearchView &operator=(const SearchView &) = delete; SearchView &operator=(SearchView &&) = delete; ~SearchView() override; - const ISummaryManager::ISummarySetup::SP & getSummarySetup() const { return _summarySetup; } - const MatchView::SP & getMatchView() const { return _matchView; } - const Matchers::SP & getMatchers() const { return _matchView->getMatchers(); } - const IndexSearchable::SP & getIndexSearchable() const { return _matchView->getIndexSearchable(); } - const IAttributeManager::SP & getAttributeManager() const { return _matchView->getAttributeManager(); } - SessionManager & getSessionManager() const { return _matchView->getSessionManager(); } - const IDocumentMetaStoreContext::SP & getDocumentMetaStore() const { return _matchView->getDocumentMetaStore(); } - DocIdLimit &getDocIdLimit() const { return _matchView->getDocIdLimit(); } + const std::shared_ptr<ISummaryManager::ISummarySetup>& getSummarySetup() const noexcept { return _summarySetup; } + const std::shared_ptr<MatchView>& getMatchView() const noexcept { return _matchView; } + const std::shared_ptr<Matchers>& getMatchers() const noexcept { return _matchView->getMatchers(); } + const std::shared_ptr<IndexSearchable>& getIndexSearchable() const noexcept { return _matchView->getIndexSearchable(); } + const std::shared_ptr<IAttributeManager>& getAttributeManager() const noexcept { return _matchView->getAttributeManager(); } + SessionManager & getSessionManager() const noexcept { return _matchView->getSessionManager(); } + const std::shared_ptr<IDocumentMetaStoreContext>& getDocumentMetaStore() const noexcept { return _matchView->getDocumentMetaStore(); } + DocIdLimit &getDocIdLimit() const noexcept { return _matchView->getDocIdLimit(); } matching::MatchingStats getMatcherStats(const vespalib::string &rankProfile) const { return _matchView->getMatcherStats(rankProfile); } std::unique_ptr<DocsumReply> getDocsums(const DocsumRequest & req) override; std::unique_ptr<SearchReply> match(const SearchRequest &req, vespalib::ThreadBundle &threadBundle) const override; private: - SearchView(ISummaryManager::ISummarySetup::SP summarySetup, MatchView::SP matchView); + SearchView(std::shared_ptr<ISummaryManager::ISummarySetup> summarySetup, std::shared_ptr<MatchView> matchView); InternalDocsumReply getDocsumsInternal(const DocsumRequest & req); - ISummaryManager::ISummarySetup::SP _summarySetup; - MatchView::SP _matchView; + std::shared_ptr<ISummaryManager::ISummarySetup> _summarySetup; + std::shared_ptr<MatchView> _matchView; }; } // namespace proton diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp index e3cf394c143..da2f24250e1 100644 --- a/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp @@ -412,7 +412,7 @@ StoreOnlyDocSubDB::prepare_reconfig(const DocumentDBConfig& new_config_snapshot, (void) old_config_snapshot; (void) reconfig_params; (void) serial_num; - return std::make_unique<DocumentSubDBReconfig>(std::shared_ptr<Matchers>()); + return std::make_unique<DocumentSubDBReconfig>(std::shared_ptr<Matchers>(), std::shared_ptr<IAttributeManager>()); } void diff --git a/searchcore/src/vespa/searchcore/proton/test/dummy_document_sub_db.h b/searchcore/src/vespa/searchcore/proton/test/dummy_document_sub_db.h index 5ab0109578c..16ec38a2ec6 100644 --- a/searchcore/src/vespa/searchcore/proton/test/dummy_document_sub_db.h +++ b/searchcore/src/vespa/searchcore/proton/test/dummy_document_sub_db.h @@ -53,7 +53,7 @@ struct DummyDocumentSubDb : public IDocumentSubDB void setup(const DocumentSubDbInitializerResult &) override {} void initViews(const DocumentDBConfig &) override {} std::unique_ptr<DocumentSubDBReconfig> prepare_reconfig(const DocumentDBConfig&, const DocumentDBConfig&, const ReconfigParams&, std::optional<SerialNum>) override { - return std::make_unique<DocumentSubDBReconfig>(std::shared_ptr<Matchers>()); + return std::make_unique<DocumentSubDBReconfig>(std::shared_ptr<Matchers>(), std::shared_ptr<IAttributeManager>()); } void complete_prepare_reconfig(DocumentSubDBReconfig&, SerialNum) override { } IReprocessingTask::List applyConfig(const DocumentDBConfig &, const DocumentDBConfig &, diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h index 2261fccd628..f85baa8c0ac 100644 --- a/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h +++ b/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h @@ -2,7 +2,7 @@ #pragma once #include <vespa/searchcore/proton/attribute/i_attribute_manager.h> -#include <vespa/searchcore/proton/attribute/attribute_manager_reconfig.h> +#include <vespa/searchcore/proton/attribute/i_attribute_manager_reconfig.h> #include <vespa/searchcore/proton/attribute/imported_attributes_repo.h> #include <vespa/searchlib/test/mock_attribute_manager.h> #include <vespa/vespalib/util/hdr_abort.h> @@ -50,12 +50,9 @@ public: search::attribute::IAttributeContext::UP createContext() const override { return _mock.createContext(); } - std::unique_ptr<AttributeManagerReconfig> prepare_create(AttributeCollectionSpec&&) const override { + std::unique_ptr<IAttributeManagerReconfig> prepare_create(AttributeCollectionSpec&&) const override { return {}; } - IAttributeManager::SP create(AttributeCollectionSpec &&) const override { - return IAttributeManager::SP(); - } std::vector<searchcorespi::IFlushTarget::SP> getFlushTargets() const override { return std::vector<searchcorespi::IFlushTarget::SP>(); } diff --git a/storage/src/tests/common/metricstest.cpp b/storage/src/tests/common/metricstest.cpp index 290d05e9a59..97d1c22364f 100644 --- a/storage/src/tests/common/metricstest.cpp +++ b/storage/src/tests/common/metricstest.cpp @@ -12,7 +12,6 @@ #include <tests/common/dummystoragelink.h> #include <vespa/metrics/metricmanager.h> #include <vespa/config/common/exceptions.h> -#include <vespa/vespalib/stllike/hash_map.hpp> #include <vespa/vespalib/gtest/gtest.h> #include <gmock/gmock.h> #include <filesystem> @@ -38,9 +37,7 @@ struct MetricsTest : public Test { std::shared_ptr<VisitorMetrics> _visitorMetrics; void createSnapshotForPeriod(std::chrono::seconds secs) const; - void assertMetricLastValue(const std::string& name, - int interval, - uint64_t expected) const; + void assertMetricLastValue(const std::string& name, int interval, uint64_t expected) const; MetricsTest(); ~MetricsTest() override; @@ -55,8 +52,8 @@ namespace { { framework::Clock& _clock; explicit MetricClock(framework::Clock& c) : _clock(c) {} - [[nodiscard]] time_t getTime() const override { return _clock.getTimeInSeconds().getTime(); } - time_t getTimeInMilliSecs() const override { return vespalib::count_ms(_clock.getMonotonicTime().time_since_epoch()); } + [[nodiscard]] time_t getTime() const override { return vespalib::count_s(_clock.getMonotonicTime().time_since_epoch()); } + [[nodiscard]] time_t getTimeInMilliSecs() const override { return vespalib::count_ms(_clock.getMonotonicTime().time_since_epoch()); } }; } @@ -192,7 +189,7 @@ void MetricsTest::createFakeLoad() } _clock->addSecondsToTime(60); _metricManager->timeChangedNotification(); - while (uint64_t(_metricManager->getLastProcessedTime()) < _clock->getTimeInSeconds().getTime()) { + while (int64_t(_metricManager->getLastProcessedTime()) < vespalib::count_s(_clock->getMonotonicTime().time_since_epoch())) { std::this_thread::sleep_for(5ms); _metricManager->timeChangedNotification(); } @@ -242,10 +239,7 @@ TEST_F(MetricsTest, snapshot_presenting) { for (uint32_t i=0; i<6; ++i) { _clock->addSecondsToTime(60); _metricManager->timeChangedNotification(); - while ( - uint64_t(_metricManager->getLastProcessedTime()) - < _clock->getTimeInSeconds().getTime()) - { + while (int64_t(_metricManager->getLastProcessedTime()) < vespalib::count_s(_clock->getMonotonicTime().time_since_epoch())) { std::this_thread::sleep_for(1ms); } } @@ -305,9 +299,7 @@ MetricsTest::createSnapshotForPeriod(std::chrono::seconds secs) const { _clock->addSecondsToTime(secs.count()); _metricManager->timeChangedNotification(); - while (uint64_t(_metricManager->getLastProcessedTime()) - < _clock->getTimeInSeconds().getTime()) - { + while (int64_t(_metricManager->getLastProcessedTime()) < vespalib::count_s(_clock->getMonotonicTime().time_since_epoch())) { std::this_thread::sleep_for(100ms); } } diff --git a/storage/src/tests/common/teststorageapp.cpp b/storage/src/tests/common/teststorageapp.cpp index ea35c2de36a..13861a7cdde 100644 --- a/storage/src/tests/common/teststorageapp.cpp +++ b/storage/src/tests/common/teststorageapp.cpp @@ -192,7 +192,7 @@ api::Timestamp TestDistributorApp::generate_unique_timestamp() { std::lock_guard guard(_accessLock); - uint64_t timeNow(getClock().getTimeInSeconds().getTime()); + uint64_t timeNow(vespalib::count_s(getClock().getSystemTime().time_since_epoch())); if (timeNow == _lastUniqueTimestampRequested) { ++_uniqueTimestampCounter; } else { diff --git a/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp b/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp index 817e9b33226..bcb5f7199f0 100644 --- a/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp +++ b/storage/src/tests/distributor/ownership_transfer_safe_time_point_calculator_test.cpp @@ -3,24 +3,10 @@ #include <vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.h> #include <vespa/vespalib/gtest/gtest.h> -namespace std::chrono { - -template <typename Clock, typename Duration> -std::ostream& operator<<(std::ostream& os, - std::chrono::time_point<Clock, Duration> t) -{ - os << std::chrono::duration_cast<std::chrono::milliseconds>( - t.time_since_epoch()).count() << "ms"; - return os; -} - -} - namespace storage::distributor { using CalcType = OwnershipTransferSafeTimePointCalculator; -using Clock = CalcType::Clock; -using TimePoint = CalcType::TimePoint; +using TimePoint = vespalib::system_time; using namespace std::literals::chrono_literals; diff --git a/storage/src/tests/storageframework/clock/timetest.cpp b/storage/src/tests/storageframework/clock/timetest.cpp index 0f18dc9ed3a..20670b3b438 100644 --- a/storage/src/tests/storageframework/clock/timetest.cpp +++ b/storage/src/tests/storageframework/clock/timetest.cpp @@ -8,15 +8,14 @@ namespace storage::framework::defaultimplementation { TEST(TimeTest, testBasics) { - MicroSecTime timeMicros(1000*1000); MicroSecTime timeMicros2 = timeMicros; EXPECT_EQ(timeMicros2, timeMicros); - timeMicros2 += MicroSecTime(25000); + timeMicros2 = MicroSecTime(timeMicros.getTime() + 25000); EXPECT_GT(timeMicros2, timeMicros); EXPECT_LT(timeMicros, timeMicros2); - timeMicros2 -= MicroSecTime(30000); + timeMicros2 = MicroSecTime(timeMicros2.getTime() - 30000); EXPECT_LT(timeMicros2, timeMicros); EXPECT_GT(timeMicros, timeMicros2); } @@ -26,7 +25,8 @@ TEST(TimeTest, testCreatedFromClock) defaultimplementation::FakeClock clock; clock.setAbsoluteTimeInSeconds(600); - EXPECT_EQ(MicroSecTime(600 * 1000 * 1000), MicroSecTime(clock)); + EXPECT_EQ(vespalib::system_time(600s), clock.getSystemTime()); + EXPECT_EQ(vespalib::steady_time(600s), clock.getMonotonicTime()); } TEST(TimeTest, canAssignMicrosecondResolutionTimeToFakeClock) @@ -34,8 +34,9 @@ TEST(TimeTest, canAssignMicrosecondResolutionTimeToFakeClock) defaultimplementation::FakeClock clock; clock.setAbsoluteTimeInMicroSeconds(1234567); // 1.234567 seconds + EXPECT_EQ(vespalib::system_time(1234567us), clock.getSystemTime()); + EXPECT_EQ(vespalib::steady_time(1234567us), clock.getMonotonicTime()); // All non-microsec time points must necessarily be truncated. - EXPECT_EQ(MicroSecTime(1234567), MicroSecTime(clock)); } } diff --git a/storage/src/tests/storageserver/statereportertest.cpp b/storage/src/tests/storageserver/statereportertest.cpp index 01cf12f7947..b7903de0fe2 100644 --- a/storage/src/tests/storageserver/statereportertest.cpp +++ b/storage/src/tests/storageserver/statereportertest.cpp @@ -228,9 +228,7 @@ TEST_F(StateReporterTest, report_metrics) { for (uint32_t i = 0; i < 6; ++i) { _clock->addSecondsToTime(60); _metricManager->timeChangedNotification(); - while ( - uint64_t(_metricManager->getLastProcessedTime()) - < _clock->getTimeInSeconds().getTime()) + while (int64_t(_metricManager->getLastProcessedTime()) < vespalib::count_s(_clock->getMonotonicTime().time_since_epoch())) { std::this_thread::sleep_for(1ms); } diff --git a/storage/src/vespa/storage/bucketdb/bucketinfo.h b/storage/src/vespa/storage/bucketdb/bucketinfo.h index cc34cfa2879..1870d4c91d4 100644 --- a/storage/src/vespa/storage/bucketdb/bucketinfo.h +++ b/storage/src/vespa/storage/bucketdb/bucketinfo.h @@ -21,6 +21,7 @@ template <typename NodeSeq> class BucketInfoBase { protected: + //TODO: Should we use a chrono timepoint to ensure we are using same clock everywhere ? uint32_t _lastGarbageCollection; NodeSeq _nodes; public: diff --git a/storage/src/vespa/storage/distributor/bucketgctimecalculator.cpp b/storage/src/vespa/storage/distributor/bucketgctimecalculator.cpp index 792530514b5..b1d8d61c173 100644 --- a/storage/src/vespa/storage/distributor/bucketgctimecalculator.cpp +++ b/storage/src/vespa/storage/distributor/bucketgctimecalculator.cpp @@ -2,20 +2,21 @@ #include "bucketgctimecalculator.h" +using vespalib::count_s; + namespace storage::distributor { bool BucketGcTimeCalculator::shouldGc(const document::BucketId& b, - std::chrono::seconds currentTime, - std::chrono::seconds lastRunAt) const + vespalib::duration currentTime, + vespalib::duration lastRunAt) const { - if (_checkInterval.count() == 0) { + if (count_s(_checkInterval) == 0) { return false; } - std::chrono::seconds gcPoint(_hasher.hash(b) % _checkInterval.count()); - std::chrono::seconds currentPeriodStart(currentTime - - (currentTime % _checkInterval)); - std::chrono::seconds newestValid(currentPeriodStart + gcPoint); + std::chrono::seconds gcPoint(_hasher.hash(b) % count_s(_checkInterval)); + vespalib::duration currentPeriodStart(currentTime - (currentTime % _checkInterval)); + vespalib::duration newestValid(currentPeriodStart + gcPoint); // Should GC have been started in current period? if (currentTime >= newestValid && lastRunAt < newestValid) { diff --git a/storage/src/vespa/storage/distributor/bucketgctimecalculator.h b/storage/src/vespa/storage/distributor/bucketgctimecalculator.h index f8d30b6e526..54abebc4152 100644 --- a/storage/src/vespa/storage/distributor/bucketgctimecalculator.h +++ b/storage/src/vespa/storage/distributor/bucketgctimecalculator.h @@ -1,8 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <chrono> #include <vespa/document/bucket/bucketid.h> +#include <vespa/vespalib/util/time.h> namespace storage::distributor { @@ -35,19 +35,19 @@ public: }; BucketGcTimeCalculator(const BucketIdHasher& hasher, - std::chrono::seconds checkInterval) + vespalib::duration checkInterval) : _hasher(hasher), _checkInterval(checkInterval) { } bool shouldGc(const document::BucketId&, - std::chrono::seconds currentTime, - std::chrono::seconds lastRunAt) const; + vespalib::duration currentTime, + vespalib::duration lastRunAt) const; private: const BucketIdHasher& _hasher; - std::chrono::seconds _checkInterval; + vespalib::duration _checkInterval; }; } diff --git a/storage/src/vespa/storage/distributor/distributor_stripe.cpp b/storage/src/vespa/storage/distributor/distributor_stripe.cpp index 2f150cf7250..782dd9d7e12 100644 --- a/storage/src/vespa/storage/distributor/distributor_stripe.cpp +++ b/storage/src/vespa/storage/distributor/distributor_stripe.cpp @@ -848,11 +848,7 @@ DistributorStripe::enable_cluster_state_bundle(const lib::ClusterStateBundle& ne // TODO STRIPE replace legacy func enableClusterStateBundle(new_state); if (has_bucket_ownership_change) { - using TimePoint = OwnershipTransferSafeTimePointCalculator::TimePoint; - // Note: this assumes that std::chrono::system_clock and the framework - // system clock have the same epoch, which should be a reasonable - // assumption. - TimePoint now = _component.getClock().getSystemTime(); + vespalib::system_time now = _component.getClock().getSystemTime(); _externalOperationHandler.rejectFeedBeforeTimeReached(_ownershipSafeTimeCalc->safeTimePoint(now)); } _bucketDBUpdater.handle_activated_cluster_state_bundle(); // Triggers resending of queued requests diff --git a/storage/src/vespa/storage/distributor/distributor_stripe_component.cpp b/storage/src/vespa/storage/distributor/distributor_stripe_component.cpp index 2a4b63ecee2..b47e0697a91 100644 --- a/storage/src/vespa/storage/distributor/distributor_stripe_component.cpp +++ b/storage/src/vespa/storage/distributor/distributor_stripe_component.cpp @@ -109,7 +109,7 @@ UpdateBucketDatabaseProcessor::process_entry(BucketDatabase::Entry &entry) const // distributor has run GC on it, we just have to assume this and set the // timestamp to the current time to avoid duplicate work. if (entry->getLastGarbageCollectionTime() == 0) { - entry->setLastGarbageCollectionTime(_clock.getTimeInSeconds().getTime()); + entry->setLastGarbageCollectionTime(vespalib::count_s(_clock.getSystemTime().time_since_epoch())); } entry->addNodes(_changed_nodes, _ideal_nodes); if (_reset_trusted) { diff --git a/storage/src/vespa/storage/distributor/externaloperationhandler.cpp b/storage/src/vespa/storage/distributor/externaloperationhandler.cpp index 0ada9da29c1..6cb404aaa0a 100644 --- a/storage/src/vespa/storage/distributor/externaloperationhandler.cpp +++ b/storage/src/vespa/storage/distributor/externaloperationhandler.cpp @@ -4,7 +4,6 @@ #include "crypto_uuid_generator.h" #include "top_level_distributor.h" #include "distributor_bucket_space.h" -#include "distributor_bucket_space_repo.h" #include "externaloperationhandler.h" #include "operation_sequencer.h" #include <vespa/document/base/documentid.h> @@ -18,7 +17,6 @@ #include <vespa/storage/distributor/operations/external/statbucketlistoperation.h> #include <vespa/storage/distributor/operations/external/statbucketoperation.h> #include <vespa/storage/distributor/operations/external/twophaseupdateoperation.h> -#include <vespa/storage/distributor/operations/external/updateoperation.h> #include <vespa/storage/distributor/operations/external/visitoroperation.h> #include <vespa/storageapi/message/persistence.h> #include <vespa/storageapi/message/removelocation.h> @@ -127,7 +125,7 @@ ExternalOperationHandler::makeSafeTimeRejectionResult(TimePoint unsafeTime) bool ExternalOperationHandler::checkSafeTimeReached(api::StorageCommand& cmd) { - const auto now = TimePoint(std::chrono::seconds(_node_ctx.clock().getTimeInSeconds().getTime())); + vespalib::system_time now = _node_ctx.clock().getSystemTime(); if (now < _rejectFeedBeforeTimeReached) { api::StorageReply::UP reply(cmd.makeReply()); reply->setResult(makeSafeTimeRejectionResult(now)); @@ -431,7 +429,7 @@ std::shared_ptr<Operation> ExternalOperationHandler::try_generate_get_operation( bounce_with_wrong_distribution(*cmd, *snapshot.context().default_active_cluster_state()); metrics.locked()->failures.wrongdistributor.inc(); } - return std::shared_ptr<Operation>(); + return {}; } // The snapshot is aware of whether stale reads are enabled, so we don't have to check that here. const auto* space_repo = snapshot.bucket_space_repo(); diff --git a/storage/src/vespa/storage/distributor/maintenance/node_maintenance_stats_tracker.h b/storage/src/vespa/storage/distributor/maintenance/node_maintenance_stats_tracker.h index 0e6c2bb23c2..deeef118685 100644 --- a/storage/src/vespa/storage/distributor/maintenance/node_maintenance_stats_tracker.h +++ b/storage/src/vespa/storage/distributor/maintenance/node_maintenance_stats_tracker.h @@ -1,11 +1,9 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <chrono> #include <unordered_map> -#include <iosfwd> -#include <stdint.h> #include <vespa/document/bucket/bucketspace.h> +#include <vespa/vespalib/util/time.h> namespace storage::distributor { @@ -53,7 +51,7 @@ public: private: PerNodeStats _node_stats; NodeMaintenanceStats _total_stats; - std::chrono::seconds _max_observed_time_since_last_gc; + vespalib::duration _max_observed_time_since_last_gc; static const NodeMaintenanceStats _emptyNodeMaintenanceStats; @@ -86,7 +84,7 @@ public: ++_total_stats.total; } - void update_observed_time_since_last_gc(std::chrono::seconds time_since_gc) noexcept { + void update_observed_time_since_last_gc(vespalib::duration time_since_gc) noexcept { _max_observed_time_since_last_gc = std::max(time_since_gc, _max_observed_time_since_last_gc); } @@ -116,7 +114,7 @@ public: return _total_stats; } - std::chrono::seconds max_observed_time_since_last_gc() const noexcept { + vespalib::duration max_observed_time_since_last_gc() const noexcept { return _max_observed_time_since_last_gc; } diff --git a/storage/src/vespa/storage/distributor/nodeinfo.cpp b/storage/src/vespa/storage/distributor/nodeinfo.cpp index d02a1e1906e..6bb1949d606 100644 --- a/storage/src/vespa/storage/distributor/nodeinfo.cpp +++ b/storage/src/vespa/storage/distributor/nodeinfo.cpp @@ -25,7 +25,7 @@ bool NodeInfo::isBusy(uint16_t idx) const { return false; } -void NodeInfo::setBusy(uint16_t idx, framework::MonotonicDuration for_duration) { +void NodeInfo::setBusy(uint16_t idx, vespalib::duration for_duration) { getNode(idx)._busyUntilTime = _clock.getMonotonicTime() + for_duration; } diff --git a/storage/src/vespa/storage/distributor/operations/idealstate/garbagecollectionoperation.cpp b/storage/src/vespa/storage/distributor/operations/idealstate/garbagecollectionoperation.cpp index d3e4e49c193..5599f9fb51e 100644 --- a/storage/src/vespa/storage/distributor/operations/idealstate/garbagecollectionoperation.cpp +++ b/storage/src/vespa/storage/distributor/operations/idealstate/garbagecollectionoperation.cpp @@ -242,8 +242,7 @@ void GarbageCollectionOperation::on_metadata_read_phase_done(DistributorStripeMe void GarbageCollectionOperation::update_last_gc_timestamp_in_db() { BucketDatabase::Entry dbentry = _bucketSpace->getBucketDatabase().get(getBucketId()); if (dbentry.valid()) { - dbentry->setLastGarbageCollectionTime( - _manager->node_context().clock().getTimeInSeconds().getTime()); + dbentry->setLastGarbageCollectionTime(vespalib::count_s(_manager->node_context().clock().getSystemTime().time_since_epoch())); LOG(debug, "GC(%s): Tagging bucket completed at time %u", getBucket().toString().c_str(), dbentry->getLastGarbageCollectionTime()); _bucketSpace->getBucketDatabase().update(dbentry); diff --git a/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.cpp b/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.cpp index 818c812ab4f..d44ea464dbc 100644 --- a/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.cpp +++ b/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.cpp @@ -5,11 +5,11 @@ namespace storage::distributor { -OwnershipTransferSafeTimePointCalculator::TimePoint -OwnershipTransferSafeTimePointCalculator::safeTimePoint(TimePoint now) const +vespalib::system_time +OwnershipTransferSafeTimePointCalculator::safeTimePoint(vespalib::system_time now) const { if (_max_cluster_clock_skew.count() == 0) { - return TimePoint{}; + return {}; } // Rationale: distributors always generate time stamps by taking // the current second and adding a synthetic microsecond counter. @@ -26,7 +26,7 @@ OwnershipTransferSafeTimePointCalculator::safeTimePoint(TimePoint now) const // the same whole second as another distributor already has done for // any of the buckets a node now owns. auto now_sec = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()); - return TimePoint(now_sec + std::chrono::seconds(1) + _max_cluster_clock_skew); + return vespalib::system_time(now_sec + std::chrono::seconds(1) + _max_cluster_clock_skew); } } diff --git a/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.h b/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.h index 9e1409854b5..84cae173ecc 100644 --- a/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.h +++ b/storage/src/vespa/storage/distributor/ownership_transfer_safe_time_point_calculator.h @@ -2,7 +2,7 @@ #pragma once -#include <chrono> +#include <vespa/vespalib/util/time.h> namespace storage::distributor { @@ -28,11 +28,7 @@ namespace storage::distributor { class OwnershipTransferSafeTimePointCalculator { std::chrono::seconds _max_cluster_clock_skew; public: - using Clock = std::chrono::system_clock; - using TimePoint = std::chrono::time_point<Clock>; - - explicit OwnershipTransferSafeTimePointCalculator( - std::chrono::seconds max_cluster_clock_skew) + explicit OwnershipTransferSafeTimePointCalculator(std::chrono::seconds max_cluster_clock_skew) : _max_cluster_clock_skew(max_cluster_clock_skew) { } @@ -41,7 +37,7 @@ public: _max_cluster_clock_skew = sec; } - TimePoint safeTimePoint(TimePoint now) const; + vespalib::system_time safeTimePoint(vespalib::system_time now) const; }; } diff --git a/storage/src/vespa/storage/distributor/pending_bucket_space_db_transition.cpp b/storage/src/vespa/storage/distributor/pending_bucket_space_db_transition.cpp index f09ef468441..62de3b50b51 100644 --- a/storage/src/vespa/storage/distributor/pending_bucket_space_db_transition.cpp +++ b/storage/src/vespa/storage/distributor/pending_bucket_space_db_transition.cpp @@ -194,7 +194,7 @@ PendingBucketSpaceDbTransition::DbMerger::addToMerger(BucketDatabase::Merger& me BucketDatabase::Entry e(bucket_id, BucketInfo()); insertInfo(e, range); if (e->getLastGarbageCollectionTime() == 0) { - e->setLastGarbageCollectionTime(framework::MicroSecTime(_creation_timestamp).getSeconds().getTime()); + e->setLastGarbageCollectionTime(framework::MicroSecTime(_creation_timestamp).getSeconds()); } e.getBucketInfo().updateTrusted(); merger.insert_before_current(bucket_id, e); @@ -212,7 +212,7 @@ PendingBucketSpaceDbTransition::DbMerger::addToInserter(BucketDatabase::Trailing BucketDatabase::Entry e(bucket_id, BucketInfo()); insertInfo(e, range); if (e->getLastGarbageCollectionTime() == 0) { - e->setLastGarbageCollectionTime(framework::MicroSecTime(_creation_timestamp).getSeconds().getTime()); + e->setLastGarbageCollectionTime(framework::MicroSecTime(_creation_timestamp).getSeconds()); } e.getBucketInfo().updateTrusted(); inserter.insert_at_end(bucket_id, e); diff --git a/storage/src/vespa/storage/distributor/pendingclusterstate.cpp b/storage/src/vespa/storage/distributor/pendingclusterstate.cpp index b9639f54469..36f7af1c1e6 100644 --- a/storage/src/vespa/storage/distributor/pendingclusterstate.cpp +++ b/storage/src/vespa/storage/distributor/pendingclusterstate.cpp @@ -210,11 +210,10 @@ PendingClusterState::requestNode(BucketSpaceAndNode bucketSpaceAndNode) } -PendingClusterState::Summary::Summary(const std::string& prevClusterState, - const std::string& newClusterState, - uint32_t processingTime) - : _prevClusterState(prevClusterState), - _newClusterState(newClusterState), +PendingClusterState::Summary::Summary(std::string prevClusterState, std::string newClusterState, + vespalib::duration processingTime) + : _prevClusterState(std::move(prevClusterState)), + _newClusterState(std::move(newClusterState)), _processingTime(processingTime) {} @@ -304,9 +303,9 @@ PendingClusterState::printXml(vespalib::XmlOutputStream& xos) const PendingClusterState::Summary PendingClusterState::getSummary() const { - return Summary(getPrevClusterStateBundleString(), - getNewClusterStateBundleString(), - (_clock.getTimeInMicros().getTime() - _creationTimestamp)); + return {getPrevClusterStateBundleString(), + getNewClusterStateBundleString(), + _clock.getSystemTime().time_since_epoch() - std::chrono::microseconds(_creationTimestamp)}; } PendingBucketSpaceDbTransition& diff --git a/storage/src/vespa/storage/distributor/pendingclusterstate.h b/storage/src/vespa/storage/distributor/pendingclusterstate.h index 8af08e1ba4d..dcc60a537f1 100644 --- a/storage/src/vespa/storage/distributor/pendingclusterstate.h +++ b/storage/src/vespa/storage/distributor/pendingclusterstate.h @@ -6,7 +6,6 @@ #include "clusterinformation.h" #include <vespa/storageapi/message/bucket.h> #include <vespa/storageapi/message/state.h> -#include <vespa/storageframework/generic/clock/clock.h> #include <vespa/vdslib/state/cluster_state_bundle.h> #include <vespa/vespalib/util/xmlserializable.h> #include <vespa/vespalib/stllike/hash_map.h> @@ -14,6 +13,8 @@ #include <unordered_map> #include <deque> +namespace storage::framework { struct Clock; } + namespace storage::distributor { class BucketSpaceStateMap; @@ -30,16 +31,16 @@ public: using OutdatedNodes = dbtransition::OutdatedNodes; using OutdatedNodesMap = dbtransition::OutdatedNodesMap; struct Summary { - Summary(const std::string& prevClusterState, const std::string& newClusterState, uint32_t processingTime); + Summary(std::string prevClusterState, std::string newClusterState, vespalib::duration processingTime); Summary(const Summary &); Summary & operator = (const Summary &); - Summary(Summary &&) = default; - Summary & operator = (Summary &&) = default; + Summary(Summary &&) noexcept = default; + Summary & operator = (Summary &&) noexcept = default; ~Summary(); std::string _prevClusterState; std::string _newClusterState; - uint32_t _processingTime; + vespalib::duration _processingTime; }; static std::unique_ptr<PendingClusterState> createForClusterStateChange( diff --git a/storage/src/vespa/storage/distributor/statechecker.cpp b/storage/src/vespa/storage/distributor/statechecker.cpp index 91acd494a7a..eaff1f0b780 100644 --- a/storage/src/vespa/storage/distributor/statechecker.cpp +++ b/storage/src/vespa/storage/distributor/statechecker.cpp @@ -72,8 +72,7 @@ StateChecker::Context::Context(const DistributorNodeContext& node_ctx_in, pending_cluster_state(op_ctx_in.pending_cluster_state_or_null(bucket_.getBucketSpace())), distributorConfig(op_ctx_in.distributor_config()), distribution(distributorBucketSpace.getDistribution()), - gcTimeCalculator(op_ctx_in.bucket_id_hasher(), - std::chrono::duration_cast<std::chrono::seconds>(distributorConfig.getGarbageCollectionInterval())), + gcTimeCalculator(op_ctx_in.bucket_id_hasher(), distributorConfig.getGarbageCollectionInterval()), node_ctx(node_ctx_in), op_ctx(op_ctx_in), db(distributorBucketSpace.getBucketDatabase()), diff --git a/storage/src/vespa/storage/distributor/statecheckers.cpp b/storage/src/vespa/storage/distributor/statecheckers.cpp index 14cc2509cab..f9c26bf113e 100644 --- a/storage/src/vespa/storage/distributor/statecheckers.cpp +++ b/storage/src/vespa/storage/distributor/statecheckers.cpp @@ -1130,7 +1130,7 @@ GarbageCollectionStateChecker::garbage_collection_disabled(const Context& c) noe } bool -GarbageCollectionStateChecker::needs_garbage_collection(const Context& c, std::chrono::seconds time_since_epoch) +GarbageCollectionStateChecker::needs_garbage_collection(const Context& c, vespalib::duration time_since_epoch) { if (c.entry->getNodeCount() == 0) { return false; @@ -1148,20 +1148,18 @@ GarbageCollectionStateChecker::check(Context& c) const if (garbage_collection_disabled(c)) { return Result::noMaintenanceNeeded(); } - const std::chrono::seconds now(c.node_ctx.clock().getTimeInSeconds().getTime()); + const vespalib::duration now(c.node_ctx.clock().getSystemTime().time_since_epoch()); const std::chrono::seconds last_run_at(c.entry->getLastGarbageCollectionTime()); c.stats.update_observed_time_since_last_gc(now - last_run_at); if (needs_garbage_collection(c, now)) { - auto op = std::make_unique<GarbageCollectionOperation>( - c.node_ctx, - BucketAndNodes(c.getBucket(), c.entry->getNodes())); + auto op = std::make_unique<GarbageCollectionOperation>(c.node_ctx, BucketAndNodes(c.getBucket(), c.entry->getNodes())); vespalib::asciistream reason; reason << "[Needs garbage collection: Last check at " << c.entry->getLastGarbageCollectionTime() << ", current time " - << now.count() + << vespalib::count_s(now) << ", configured interval " << vespalib::to_s(c.distributorConfig.getGarbageCollectionInterval()) << "]"; diff --git a/storage/src/vespa/storage/distributor/statecheckers.h b/storage/src/vespa/storage/distributor/statecheckers.h index c1579cb5eda..b6cd5ba0534 100644 --- a/storage/src/vespa/storage/distributor/statecheckers.h +++ b/storage/src/vespa/storage/distributor/statecheckers.h @@ -88,7 +88,7 @@ public: const char* getName() const noexcept override { return "GarbageCollection"; } private: static bool garbage_collection_disabled(const Context& c) noexcept; - static bool needs_garbage_collection(const Context& c, std::chrono::seconds time_since_epoch); + static bool needs_garbage_collection(const Context& c, vespalib::duration time_since_epoch); }; } diff --git a/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.cpp b/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.cpp index f69f9e3d427..8fce8c3137a 100644 --- a/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.cpp +++ b/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.cpp @@ -92,9 +92,8 @@ StripeBucketDBUpdater::flush() } void -StripeBucketDBUpdater::print(std::ostream& out, bool verbose, const std::string& indent) const +StripeBucketDBUpdater::print(std::ostream& out, bool, const std::string&) const { - (void) verbose; (void) indent; out << "StripeBucketDBUpdater"; } @@ -461,9 +460,8 @@ StripeBucketDBUpdater::resendDelayedMessages() } void -StripeBucketDBUpdater::convertBucketInfoToBucketList( - const std::shared_ptr<api::RequestBucketInfoReply>& repl, - uint16_t targetNode, BucketListMerger::BucketList& newList) +StripeBucketDBUpdater::convertBucketInfoToBucketList(const std::shared_ptr<api::RequestBucketInfoReply>& repl, + uint16_t targetNode, BucketListMerger::BucketList& newList) { for (const auto & entry : repl->getBucketInfo()) { LOG(debug, "Received bucket information from node %u for bucket %s: %s", targetNode, @@ -492,8 +490,7 @@ StripeBucketDBUpdater::mergeBucketInfoWithDatabase( } bool -StripeBucketDBUpdater::processSingleBucketInfoReply( - const std::shared_ptr<api::RequestBucketInfoReply> & repl) +StripeBucketDBUpdater::processSingleBucketInfoReply(const std::shared_ptr<api::RequestBucketInfoReply> & repl) { auto iter = _sentMessages.find(repl->getMsgId()); @@ -520,10 +517,8 @@ StripeBucketDBUpdater::processSingleBucketInfoReply( } void -StripeBucketDBUpdater::addBucketInfoForNode( - const BucketDatabase::Entry& e, - uint16_t node, - BucketListMerger::BucketList& existing) const +StripeBucketDBUpdater::addBucketInfoForNode(const BucketDatabase::Entry& e, uint16_t node, + BucketListMerger::BucketList& existing) { const BucketCopy* copy(e->getNode(node)); if (copy) { @@ -675,7 +670,7 @@ StripeBucketDBUpdater::MergingNodeRemover::MergingNodeRemover( } void -StripeBucketDBUpdater::MergingNodeRemover::logRemove(const document::BucketId& bucketId, const char* msg) const +StripeBucketDBUpdater::MergingNodeRemover::logRemove(const document::BucketId& bucketId, const char* msg) { LOG(spam, "Removing bucket %s: %s", bucketId.toString().c_str(), msg); } @@ -801,10 +796,10 @@ namespace { class MergingGcTimeSetter : public BucketDatabase::MergingProcessor { // time_point would be preferable, but the internal DB representation is seconds since epoch - std::chrono::seconds _last_gc_at_secs_from_epoch; + vespalib::system_time _last_gc; public: - explicit MergingGcTimeSetter(std::chrono::seconds gc_time_point) noexcept - : _last_gc_at_secs_from_epoch(gc_time_point) { + explicit MergingGcTimeSetter(vespalib::system_time gc_time_point) noexcept + : _last_gc(gc_time_point) { } ~MergingGcTimeSetter() override = default; @@ -812,7 +807,7 @@ public: Result merge(BucketDatabase::Merger& merger) override { auto& entry = merger.current_entry(); // TODO widen internal GC time type...! - entry->setLastGarbageCollectionTime(static_cast<uint32_t>(_last_gc_at_secs_from_epoch.count())); + entry->setLastGarbageCollectionTime(static_cast<uint32_t>(vespalib::count_s(_last_gc.time_since_epoch()))); return Result::Update; } @@ -821,10 +816,7 @@ public: } void StripeBucketDBUpdater::reset_all_last_gc_timestamps_to_current_time() { - // Epochs are expected to be identical between clock types - // TODO remove framework clock types in favor of std::chrono - auto now_from_epoch = std::chrono::seconds(_node_ctx.clock().getTimeInSeconds().getTime()); - MergingGcTimeSetter gc_time_setter(now_from_epoch); + MergingGcTimeSetter gc_time_setter(_node_ctx.clock().getSystemTime()); auto& repo = _op_ctx.bucket_space_repo(); for (auto& bucket_space : repo) { diff --git a/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.h b/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.h index 4b25c9c6fcb..04efe91e9e7 100644 --- a/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.h +++ b/storage/src/vespa/storage/distributor/stripe_bucket_db_updater.h @@ -144,12 +144,12 @@ private: const BucketRequest& req); void mergeBucketInfoWithDatabase(const std::shared_ptr<api::RequestBucketInfoReply>& repl, const BucketRequest& req); - void convertBucketInfoToBucketList(const std::shared_ptr<api::RequestBucketInfoReply>& repl, - uint16_t targetNode, BucketListMerger::BucketList& newList); + static void convertBucketInfoToBucketList(const std::shared_ptr<api::RequestBucketInfoReply>& repl, + uint16_t targetNode, BucketListMerger::BucketList& newList); void sendRequestBucketInfo(uint16_t node, const document::Bucket& bucket, - const std::shared_ptr<MergeReplyGuard>& mergeReply); - void addBucketInfoForNode(const BucketDatabase::Entry& e, uint16_t node, - BucketListMerger::BucketList& existing) const; + const std::shared_ptr<MergeReplyGuard>& mergeReplystatic ); + static void addBucketInfoForNode(const BucketDatabase::Entry& e, uint16_t node, + BucketListMerger::BucketList& existing); void clearReadOnlyBucketRepoDatabases(); /** * Adds all buckets contained in the bucket database @@ -197,7 +197,7 @@ private: ~MergingNodeRemover() override; Result merge(BucketDatabase::Merger&) override; - void logRemove(const document::BucketId& bucketId, const char* msg) const; + static void logRemove(const document::BucketId& bucketId, const char* msg) ; bool distributorOwnsBucket(const document::BucketId&) const; const std::vector<BucketDatabase::Entry>& getNonOwnedEntries() const noexcept { diff --git a/storage/src/vespa/storage/distributor/top_level_bucket_db_updater.cpp b/storage/src/vespa/storage/distributor/top_level_bucket_db_updater.cpp index 16be7733c1a..45d7bfc992c 100644 --- a/storage/src/vespa/storage/distributor/top_level_bucket_db_updater.cpp +++ b/storage/src/vespa/storage/distributor/top_level_bucket_db_updater.cpp @@ -493,7 +493,7 @@ TopLevelBucketDBUpdater::report_xml_status(vespalib::xml::XmlOutputStream& xos, xos << XmlTag("change") << XmlAttribute("from", i->_prevClusterState) << XmlAttribute("to", i->_newClusterState) - << XmlAttribute("processingtime", i->_processingTime) + << XmlAttribute("processingtime", vespalib::count_us(i->_processingTime)) << XmlEndTag(); } xos << XmlEndTag() diff --git a/storage/src/vespa/storage/distributor/top_level_distributor.cpp b/storage/src/vespa/storage/distributor/top_level_distributor.cpp index b0702ac7bf0..80c096135fa 100644 --- a/storage/src/vespa/storage/distributor/top_level_distributor.cpp +++ b/storage/src/vespa/storage/distributor/top_level_distributor.cpp @@ -145,9 +145,8 @@ TopLevelDistributor::onOpen() _threadPool.start(_component.getThreadPool()); start_stripe_pool(); } else { - LOG(warning, "Not starting distributor thread as it's configured to " - "run. Unless you are just running a test tool, this is a " - "fatal error."); + LOG(warning, "Not starting distributor thread as it's configured to run. Unless you are just running a " + "test tool, this is a fatal error."); } } @@ -313,8 +312,7 @@ TopLevelDistributor::storageDistributionChanged() _next_distribution = _component.getDistribution(); } else { LOG(debug, "Got distribution change, but the distribution %s was the same as before: %s", - _component.getDistribution()->toString().c_str(), - _distribution->toString().c_str()); + _component.getDistribution()->toString().c_str(), _distribution->toString().c_str()); } } @@ -457,15 +455,14 @@ TopLevelDistributor::enable_next_config_if_changed() void TopLevelDistributor::un_inhibit_maintenance_if_safe_time_passed() { - if (_maintenance_safe_time_point.time_since_epoch().count() != 0) { - using TimePoint = OwnershipTransferSafeTimePointCalculator::TimePoint; - const auto now = TimePoint(std::chrono::seconds(_component.clock().getTimeInSeconds().getTime())); + if (vespalib::count_s(_maintenance_safe_time_point.time_since_epoch()) != 0) { + const auto now = _component.clock().getSystemTime(); if (now >= _maintenance_safe_time_point) { // Thread safe. Relaxed store is fine; stripes will eventually observe new flag status. for (auto& stripe : _stripes) { stripe->inhibit_non_activation_maintenance_operations(false); } - _maintenance_safe_time_point = TimePoint{}; + _maintenance_safe_time_point = {}; LOG(debug, "Marked all stripes as no longer inhibiting non-activation maintenance operations"); } } diff --git a/storage/src/vespa/storage/distributor/top_level_distributor.h b/storage/src/vespa/storage/distributor/top_level_distributor.h index e8b3ecbf741..aa3a7b3655d 100644 --- a/storage/src/vespa/storage/distributor/top_level_distributor.h +++ b/storage/src/vespa/storage/distributor/top_level_distributor.h @@ -208,11 +208,11 @@ private: mutable std::vector<std::shared_ptr<DistributorStatus>> _fetched_status_requests; mutable std::mutex _stripe_scan_notify_mutex; std::vector<StripeScanStats> _stripe_scan_stats; // Indices are 1-1 with _stripes entries - std::chrono::steady_clock::time_point _last_host_info_send_time; - std::chrono::milliseconds _host_info_send_delay; + vespalib::steady_time _last_host_info_send_time; + vespalib::duration _host_info_send_delay; // Ideally this would use steady_clock, but for now let's use the same semantics as // feed blocking during safe time periods. - std::chrono::system_clock::time_point _maintenance_safe_time_point; + vespalib::system_time _maintenance_safe_time_point; std::chrono::seconds _maintenance_safe_time_delay; framework::ThreadWaitInfo _tickResult; MetricUpdateHook _metricUpdateHook; diff --git a/storage/src/vespa/storage/persistence/filestorage/mergestatus.h b/storage/src/vespa/storage/persistence/filestorage/mergestatus.h index 05ffd1336a2..1bba743c6e1 100644 --- a/storage/src/vespa/storage/persistence/filestorage/mergestatus.h +++ b/storage/src/vespa/storage/persistence/filestorage/mergestatus.h @@ -6,6 +6,7 @@ #include <vespa/storageapi/messageapi/storagereply.h> #include <vespa/storageapi/message/bucket.h> #include <vespa/storageframework/generic/clock/timer.h> +#include <vespa/storageframework/generic/clock/time.h> #include <vector> #include <deque> diff --git a/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp b/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp index 0e8ab412b16..4d1c1c34e04 100644 --- a/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp +++ b/storage/src/vespa/storage/persistence/filestorage/modifiedbucketchecker.cpp @@ -8,6 +8,7 @@ #include <vespa/config/subscription/configuri.h> #include <vespa/config/helper/configfetcher.hpp> #include <algorithm> +#include <unistd.h> #include <vespa/log/log.h> LOG_SETUP(".persistence.filestor.modifiedbucketchecker"); diff --git a/storage/src/vespa/storage/persistence/mergehandler.h b/storage/src/vespa/storage/persistence/mergehandler.h index b579677ac24..bcea51f50e1 100644 --- a/storage/src/vespa/storage/persistence/mergehandler.h +++ b/storage/src/vespa/storage/persistence/mergehandler.h @@ -26,6 +26,8 @@ namespace vespalib { class ISequencedTaskExecutor; } namespace document { class Document; } namespace storage { +namespace framework { struct Clock; } + namespace spi { struct PersistenceProvider; class Context; diff --git a/storage/src/vespa/storage/persistence/types.h b/storage/src/vespa/storage/persistence/types.h index 60de7dea4fd..c3d7f9eab6d 100644 --- a/storage/src/vespa/storage/persistence/types.h +++ b/storage/src/vespa/storage/persistence/types.h @@ -1,29 +1,18 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <iosfwd> -#include <vespa/document/bucket/bucketid.h> -#include <vespa/document/base/documentid.h> -#include <vespa/storage/bucketdb/storbucketdb.h> #include <vespa/storageapi/buckets/bucketinfo.h> -#include <vespa/storageapi/defs.h> -#include <vespa/vespalib/stllike/string.h> -#include <vespa/storageframework/generic/clock/time.h> +#include <memory> namespace storage { class MessageTracker; struct Types { - using BucketId = document::BucketId; - using DocumentId = document::DocumentId; - using GlobalId = document::GlobalId; - using Timestamp = framework::MicroSecTime; - using String = vespalib::string; using BucketInfo = api::BucketInfo; using MessageTrackerUP = std::unique_ptr<MessageTracker>; protected: - ~Types() {} // Noone should refer to objects as Types objects + ~Types() = default; // Noone should refer to objects as Types objects }; } // storage diff --git a/storage/src/vespa/storage/storageserver/bouncer.cpp b/storage/src/vespa/storage/storageserver/bouncer.cpp index 63f1cd674f8..cfe283edb9b 100644 --- a/storage/src/vespa/storage/storageserver/bouncer.cpp +++ b/storage/src/vespa/storage/storageserver/bouncer.cpp @@ -312,7 +312,7 @@ Bouncer::onDown(const std::shared_ptr<api::StorageMessage>& msg) uint64_t timestamp = extractMutationTimestampIfAny(*msg); if (timestamp != 0) { timestamp /= 1000000; - uint64_t currentTime = _component.getClock().getTimeInSeconds().getTime(); + uint64_t currentTime = vespalib::count_s(_component.getClock().getSystemTime().time_since_epoch()); if (timestamp > currentTime + maxClockSkewInSeconds) { rejectCommandWithTooHighClockSkew(*msg, maxClockSkewInSeconds); return true; diff --git a/storage/src/vespa/storage/storageserver/distributornode.cpp b/storage/src/vespa/storage/storageserver/distributornode.cpp index 6fd8cded08e..45abd34e131 100644 --- a/storage/src/vespa/storage/storageserver/distributornode.cpp +++ b/storage/src/vespa/storage/storageserver/distributornode.cpp @@ -86,7 +86,7 @@ DistributorNode::createChain(IStorageChainBuilder &builder) // TODO: All components in this chain should use a common thread instead of // each having its own configfetcher. StorageLink::UP chain; - if (_retrievedCommunicationManager.get()) { + if (_retrievedCommunicationManager) { builder.add(std::move(_retrievedCommunicationManager)); } else { auto communication_manager = std::make_unique<CommunicationManager>(dcr, _configUri); @@ -111,7 +111,7 @@ DistributorNode::createChain(IStorageChainBuilder &builder) api::Timestamp DistributorNode::generate_unique_timestamp() { - uint64_t now_seconds = _component->getClock().getTimeInSeconds().getTime(); + uint64_t now_seconds = vespalib::count_s(_component->getClock().getSystemTime().time_since_epoch()); std::lock_guard lock(_timestamp_mutex); // We explicitly handle a seemingly decreased wall clock time, as multiple threads may // race with each other over a second change edge. In this case, pretend an earlier @@ -139,7 +139,7 @@ DistributorNode::generate_unique_timestamp() ResumeGuard DistributorNode::pause() { - return ResumeGuard(); + return {}; } } // storage diff --git a/storage/src/vespa/storage/storageserver/distributornodecontext.cpp b/storage/src/vespa/storage/storageserver/distributornodecontext.cpp index c74490a18aa..f3aca7a427d 100644 --- a/storage/src/vespa/storage/storageserver/distributornodecontext.cpp +++ b/storage/src/vespa/storage/storageserver/distributornodecontext.cpp @@ -1,13 +1,12 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "distributornodecontext.h" +#include <vespa/storageframework/generic/clock/clock.h> namespace storage { -DistributorNodeContext::DistributorNodeContext( - framework::Clock::UP clock) - : StorageNodeContext(StorageComponentRegisterImpl::UP(new DistributorComponentRegisterImpl), - std::move(clock)), +DistributorNodeContext::DistributorNodeContext(std::unique_ptr<framework::Clock> clock) + : StorageNodeContext(std::make_unique<DistributorComponentRegisterImpl>(), std::move(clock)), _componentRegister(dynamic_cast<ComponentRegister&>(StorageNodeContext::getComponentRegister())) { } diff --git a/storage/src/vespa/storage/storageserver/distributornodecontext.h b/storage/src/vespa/storage/storageserver/distributornodecontext.h index d01127827e0..5691d014d1f 100644 --- a/storage/src/vespa/storage/storageserver/distributornodecontext.h +++ b/storage/src/vespa/storage/storageserver/distributornodecontext.h @@ -25,8 +25,7 @@ struct DistributorNodeContext : public StorageNodeContext { * You can provide your own clock implementation. Useful in testing where * you want to fake the clock. */ - DistributorNodeContext( - framework::Clock::UP clock = framework::Clock::UP(new RealClock)); + DistributorNodeContext(std::unique_ptr<framework::Clock> clock); /** * Get the actual component register. Available as the actual type as the diff --git a/storage/src/vespa/storage/storageserver/servicelayernodecontext.cpp b/storage/src/vespa/storage/storageserver/servicelayernodecontext.cpp index 544477c7ca5..12985d2476f 100644 --- a/storage/src/vespa/storage/storageserver/servicelayernodecontext.cpp +++ b/storage/src/vespa/storage/storageserver/servicelayernodecontext.cpp @@ -1,10 +1,11 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "servicelayernodecontext.h" +#include <vespa/storageframework/generic/clock/clock.h> namespace storage { -ServiceLayerNodeContext::ServiceLayerNodeContext(framework::Clock::UP clock, const ContentBucketDbOptions& db_opts) +ServiceLayerNodeContext::ServiceLayerNodeContext(std::unique_ptr<framework::Clock> clock, const ContentBucketDbOptions& db_opts) : StorageNodeContext(std::make_unique<ServiceLayerComponentRegisterImpl>(db_opts), std::move(clock)), _componentRegister(dynamic_cast<ComponentRegister&>(StorageNodeContext::getComponentRegister())) diff --git a/storage/src/vespa/storage/storageserver/servicelayernodecontext.h b/storage/src/vespa/storage/storageserver/servicelayernodecontext.h index d89ba472f83..72cf95ef120 100644 --- a/storage/src/vespa/storage/storageserver/servicelayernodecontext.h +++ b/storage/src/vespa/storage/storageserver/servicelayernodecontext.h @@ -25,7 +25,7 @@ struct ServiceLayerNodeContext : public StorageNodeContext { * You can provide your own clock implementation. Useful in testing where * you want to fake the clock. */ - ServiceLayerNodeContext(framework::Clock::UP clock, const ContentBucketDbOptions& db_opts); + ServiceLayerNodeContext(std::unique_ptr<framework::Clock> clock, const ContentBucketDbOptions& db_opts); /** * Get the actual component register. Available as the actual type as the diff --git a/storage/src/vespa/storage/storageserver/storagenodecontext.cpp b/storage/src/vespa/storage/storageserver/storagenodecontext.cpp index df087208425..ae7948a2916 100644 --- a/storage/src/vespa/storage/storageserver/storagenodecontext.cpp +++ b/storage/src/vespa/storage/storageserver/storagenodecontext.cpp @@ -1,10 +1,11 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "storagenodecontext.h" +#include <vespa/storageframework/generic/clock/clock.h> namespace storage { -StorageNodeContext::StorageNodeContext(ComponentRegister::UP compReg, framework::Clock::UP clock) +StorageNodeContext::StorageNodeContext(std::unique_ptr<ComponentRegister> compReg, std::unique_ptr<framework::Clock> clock) : _componentRegister(std::move(compReg)), _clock(std::move(clock)), _threadPool(*_clock) diff --git a/storage/src/vespa/storage/storageserver/storagenodecontext.h b/storage/src/vespa/storage/storageserver/storagenodecontext.h index c89bb4630ce..f07bdd37cd4 100644 --- a/storage/src/vespa/storage/storageserver/storagenodecontext.h +++ b/storage/src/vespa/storage/storageserver/storagenodecontext.h @@ -13,7 +13,6 @@ #pragma once #include <vespa/storage/frameworkimpl/component/storagecomponentregisterimpl.h> -#include <vespa/storageframework/defaultimplementation/clock/realclock.h> #include <vespa/storageframework/defaultimplementation/thread/threadpoolimpl.h> namespace storage { @@ -21,7 +20,6 @@ namespace storage { struct StorageNodeContext { // Typedefs to simplify the remainder of the interface using ComponentRegister = StorageComponentRegisterImpl; - using RealClock = framework::defaultimplementation::RealClock; /** * Get the actual component register. Available as the actual type as the @@ -41,11 +39,11 @@ struct StorageNodeContext { protected: // Initialization has been split in two as subclass needs to initialize // component register before sending it on. - StorageNodeContext(ComponentRegister::UP, framework::Clock::UP); + StorageNodeContext(std::unique_ptr<ComponentRegister>, std::unique_ptr<framework::Clock>); private: - ComponentRegister::UP _componentRegister; - framework::Clock::UP _clock; + std::unique_ptr<ComponentRegister> _componentRegister; + std::unique_ptr<framework::Clock> _clock; framework::defaultimplementation::ThreadPoolImpl _threadPool; }; diff --git a/storage/src/vespa/storage/visiting/commandqueue.h b/storage/src/vespa/storage/visiting/commandqueue.h index c9c34b7b4e0..c6cfd60c628 100644 --- a/storage/src/vespa/storage/visiting/commandqueue.h +++ b/storage/src/vespa/storage/visiting/commandqueue.h @@ -87,8 +87,6 @@ public: _cached_size(0) {} - const framework::Clock& getTimer() const { return _clock; } - iterator begin() { return _commands.begin(); } iterator end() { return _commands.end(); } diff --git a/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.cpp b/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.cpp index 331b2113838..5221d8a112e 100644 --- a/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.cpp +++ b/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.cpp @@ -3,20 +3,20 @@ namespace storage::framework::defaultimplementation { -FakeClock::FakeClock(Mode m, framework::MicroSecTime startTime) +FakeClock::FakeClock(Mode m, vespalib::duration startTime) : _mode(m), _absoluteTime(startTime), _cycleCount(0) { } -framework::MicroSecTime +int64_t FakeClock::getTimeInMicros() const { std::lock_guard guard(_lock); - if (_mode == FAKE_ABSOLUTE) return _absoluteTime; - MicroSecTime tmp(_absoluteTime); - tmp += framework::MicroSecTime(1000000 * _cycleCount++); - return tmp; + if (_mode == FAKE_ABSOLUTE) return vespalib::count_us(_absoluteTime); + vespalib::duration tmp(_absoluteTime); + tmp += std::chrono::seconds(_cycleCount++); + return vespalib::count_us(tmp); } } diff --git a/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h b/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h index b97c2bd92c1..395544fd175 100644 --- a/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h +++ b/storage/src/vespa/storageframework/defaultimplementation/clock/fakeclock.h @@ -22,13 +22,12 @@ struct FakeClock : public framework::Clock { private: Mode _mode; - framework::MicroSecTime _absoluteTime; + vespalib::duration _absoluteTime; mutable time_t _cycleCount; mutable std::mutex _lock; public: - FakeClock(Mode m = FAKE_ABSOLUTE, - framework::MicroSecTime startTime = framework::MicroSecTime(1)); + explicit FakeClock(Mode m = FAKE_ABSOLUTE, vespalib::duration startTime = 1us); void setMode(Mode m) { std::lock_guard guard(_lock); @@ -38,39 +37,37 @@ public: virtual void setAbsoluteTimeInSeconds(uint32_t seconds) { std::lock_guard guard(_lock); - _absoluteTime = framework::MicroSecTime(seconds * uint64_t(1000000)); + _absoluteTime = std::chrono::seconds(seconds); _cycleCount = 0; _mode = FAKE_ABSOLUTE; } virtual void setAbsoluteTimeInMicroSeconds(uint64_t usecs) { std::lock_guard guard(_lock); - _absoluteTime = framework::MicroSecTime(usecs); + _absoluteTime = std::chrono::microseconds(usecs); _cycleCount = 0; _mode = FAKE_ABSOLUTE; } virtual void addMilliSecondsToTime(uint64_t ms) { std::lock_guard guard(_lock); - _absoluteTime += framework::MicroSecTime(ms * 1000); + _absoluteTime += std::chrono::milliseconds(ms); } virtual void addSecondsToTime(uint32_t nr) { std::lock_guard guard(_lock); - _absoluteTime += framework::MicroSecTime(nr * uint64_t(1000000)); + _absoluteTime += std::chrono::seconds(nr); } - framework::MicroSecTime getTimeInMicros() const override ; - framework::SecondTime getTimeInSeconds() const override { - return getTimeInMicros().getSeconds(); - } + int64_t getTimeInMicros() const; + vespalib::system_time getSystemTime() const override { // For simplicity, assume fake monotonic time follows fake wall clock. - return vespalib::system_time(std::chrono::microseconds(getTimeInMicros().getTime())); + return vespalib::system_time(std::chrono::microseconds(getTimeInMicros())); } vespalib::steady_time getMonotonicTime() const override { // For simplicity, assume fake monotonic time follows fake wall clock. - return vespalib::steady_time(std::chrono::microseconds(getTimeInMicros().getTime())); + return vespalib::steady_time(std::chrono::microseconds(getTimeInMicros())); } }; diff --git a/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp b/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp index 2e2894de9d5..9beb55bdef3 100644 --- a/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp +++ b/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.cpp @@ -5,20 +5,6 @@ namespace storage::framework::defaultimplementation { -MicroSecTime -RealClock::getTimeInMicros() const { - struct timeval mytime; - gettimeofday(&mytime, 0); - return MicroSecTime(mytime.tv_sec * 1000000llu + mytime.tv_usec); -} - -SecondTime -RealClock::getTimeInSeconds() const { - struct timeval mytime; - gettimeofday(&mytime, 0); - return SecondTime(mytime.tv_sec); -} - vespalib::steady_time RealClock::getMonotonicTime() const { return vespalib::steady_clock::now(); diff --git a/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.h b/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.h index dc4884b4439..3a9a127defe 100644 --- a/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.h +++ b/storage/src/vespa/storageframework/defaultimplementation/clock/realclock.h @@ -14,8 +14,6 @@ namespace storage::framework::defaultimplementation { struct RealClock : public Clock { - MicroSecTime getTimeInMicros() const override; - SecondTime getTimeInSeconds() const override; vespalib::steady_time getMonotonicTime() const override; vespalib::system_time getSystemTime() const override; }; diff --git a/storage/src/vespa/storageframework/generic/clock/clock.h b/storage/src/vespa/storageframework/generic/clock/clock.h index 21d6bc589a6..5a591fa0718 100644 --- a/storage/src/vespa/storageframework/generic/clock/clock.h +++ b/storage/src/vespa/storageframework/generic/clock/clock.h @@ -13,22 +13,16 @@ #pragma once -#include "time.h" -#include <memory> +#include <vespa/vespalib/util/time.h> namespace storage::framework { struct Clock { - using UP = std::unique_ptr<Clock>; - virtual ~Clock() = default; - virtual MicroSecTime getTimeInMicros() const = 0; - virtual SecondTime getTimeInSeconds() const = 0; - // Time point resolution is intentionally not defined here. - virtual vespalib::steady_time getMonotonicTime() const = 0; - virtual vespalib::system_time getSystemTime() const = 0; + [[nodiscard]] virtual vespalib::steady_time getMonotonicTime() const = 0; + [[nodiscard]] virtual vespalib::system_time getSystemTime() const = 0; }; } diff --git a/storage/src/vespa/storageframework/generic/clock/time.cpp b/storage/src/vespa/storageframework/generic/clock/time.cpp index f5426901e4c..a27caa44d40 100644 --- a/storage/src/vespa/storageframework/generic/clock/time.cpp +++ b/storage/src/vespa/storageframework/generic/clock/time.cpp @@ -1,89 +1,17 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "time.hpp" -#include "clock.h" -#include <iomanip> -#include <vector> -#include <cassert> -#include <sstream> +#include "time.h" +#include <vespa/vespalib/stllike/asciistream.h> namespace storage::framework { -namespace { - void detectUnit(uint64_t& val, const char* unit, uint64_t size, - std::vector<std::pair<uint64_t, vespalib::string> >& units) { - if (val / size > 0) { - uint64_t value = val / size; - vespalib::string unitname = unit; - if (value != 1) unitname += "s"; - units.emplace_back(value, unitname); - val -= value * size; - } - } +std::ostream& operator<<(std::ostream& out, const MicroSecTime & t) { + return out << t.getTime(); } -vespalib::string -getTimeString(uint64_t microSecondTime, TimeFormat format) -{ - // Rewrite to use other type of stream later if needed for performance - std::ostringstream ost; - if (format & DIFFERENCE_ALL) { - std::vector<std::pair<uint64_t, vespalib::string> > vals; - detectUnit(microSecondTime, "day", 24 * 60 * 60 * 1000 * 1000ull, vals); - detectUnit(microSecondTime, "hour", 60 * 60 * 1000 * 1000ull, vals); - detectUnit(microSecondTime, "minute", 60 * 1000 * 1000, vals); - detectUnit(microSecondTime, "second", 1000 * 1000, vals); - if (format & DIFFERENCE_WITH_MICROS) { - detectUnit(microSecondTime, "microsecond", 1, vals); - if (vals.empty()) { ost << "0 microseconds"; } - } else { - if (vals.empty()) { ost << "0 seconds"; } - } - if (vals.empty()) { - return ost.str(); - } - ost << vals[0].first << " " << vals[0].second; - for (uint32_t i=1; i<vals.size(); ++i) { - if (i + 1 >= vals.size()) { - ost << " and "; - } else { - ost << ", "; - } - ost << vals[i].first << " " << vals[i].second; - } - return ost.str(); - } - time_t secondTime = microSecondTime / 1000000; - struct tm datestruct; - struct tm* datestructptr = gmtime_r(&secondTime, &datestruct); - assert(datestructptr); - (void) datestructptr; - ost << std::setfill('0') - << std::setw(4) << (datestruct.tm_year + 1900) - << '-' << std::setw(2) << (datestruct.tm_mon + 1) - << '-' << std::setw(2) << datestruct.tm_mday - << ' ' << std::setw(2) << datestruct.tm_hour - << ':' << std::setw(2) << datestruct.tm_min - << ':' << std::setw(2) << datestruct.tm_sec; - uint64_t micros = microSecondTime % 1000000; - if (format == DATETIME_WITH_MILLIS) { - ost << '.' << std::setw(3) << (micros / 1000); - } else if (format == DATETIME_WITH_MICROS) { - ost << '.' << std::setw(6) << micros; - } - return ost.str(); -} -uint64_t -getRawMicroTime(const Clock& clock) -{ - return clock.getTimeInMicros().getTime(); +vespalib::asciistream& operator<<(vespalib::asciistream& out, const MicroSecTime & t) { + return out << t.getTime(); } -template std::ostream& operator<< <MicroSecTime, 1>(std::ostream&, const Time<MicroSecTime, 1> &); -template std::ostream& operator<< <SecondTime, 1000000>(std::ostream&, const Time<SecondTime, 1000000> &); - -template vespalib::asciistream& operator<< <MicroSecTime, 1>(vespalib::asciistream &, const Time<MicroSecTime, 1> &); -template vespalib::asciistream& operator<< <SecondTime, 1000000>(vespalib::asciistream &, const Time<SecondTime, 1000000> &); - } diff --git a/storage/src/vespa/storageframework/generic/clock/time.h b/storage/src/vespa/storageframework/generic/clock/time.h index 6f7cb490355..7d2b3602432 100644 --- a/storage/src/vespa/storageframework/generic/clock/time.h +++ b/storage/src/vespa/storageframework/generic/clock/time.h @@ -1,7 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/vespalib/stllike/string.h> #include <vespa/vespalib/util/time.h> namespace vespalib { @@ -10,108 +9,6 @@ namespace vespalib { namespace storage::framework { -using MonotonicTimePoint = vespalib::steady_time; -using MonotonicDuration = vespalib::duration; - -struct Clock; - -enum TimeFormat { - DATETIME = 0x01, // 2010-04-26 19:23:03 - DATETIME_WITH_MILLIS = 0x02, // 2010-04-26 19:23:03.001 - DATETIME_WITH_MICROS = 0x04, // 2010-04-26 19:23:03.001023 - DATETIME_ALL = 0x07, - DIFFERENCE = 0x10, // 1 day, 4 hours, 43 minutes and 3 seconds - DIFFERENCE_WITH_MICROS = 0x20, // 1 day, 4 hours, 43 minutes, 3 seconds and 123123 microseconds - DIFFERENCE_ALL = 0x30 -}; - -/** - * Utility function used by Time instances (to avoid implementation in - * header file). - */ -vespalib::string getTimeString(uint64_t microSecondTime, TimeFormat format); - -// TODO deprecate framework time point and duration classes in favor of -// using std::chrono. - -// As this class can't include clock, this utility function can be used in -// header implementation to get actual time. -uint64_t getRawMicroTime(const Clock&); - -/** - * Class containing common functionality for the various time instances. Try to - * make time instances as easy to use as possible, without creating risk of - * automatic conversion between time types. - */ -template<typename Type, int MicrosPerUnit> -class Time -{ - uint64_t _time; // time_t may be signed. Negative timestamps is just a - // source for bugs. Enforce unsigned. - -protected: - explicit Time(uint64_t t) : _time(t) {} - -public: - [[nodiscard]] uint64_t getTime() const { return _time; } - void setTime(uint64_t t) { _time = t; } - [[nodiscard]] bool isSet() const { return (_time != 0); } - - Type& operator-=(const Type& o) { _time -= o._time; return static_cast<Type&>(*this); } - Type& operator+=(const Type& o) { _time += o._time; return static_cast<Type&>(*this); } - bool operator<(const Type& o) const { return (_time < o._time); } - bool operator<=(const Type& o) const { return (_time <= o._time); } - bool operator>=(const Type& o) const { return (_time >= o._time); } - bool operator>(const Type& o) const { return (_time > o._time); } - bool operator==(const Type& o) const { return (_time == o._time); } - Type& operator++() { ++_time; return static_cast<Type&>(*this); } - Type& operator--() { --_time; return *this; } - - [[nodiscard]] vespalib::string toString(TimeFormat timeFormat = DATETIME) const { - return getTimeString(_time * MicrosPerUnit, timeFormat); - } - - static Type max() { return Type(std::numeric_limits<uint64_t>::max()); } - static Type min() { return Type(0); } - -}; - -template<typename Type, typename Number> -Type& operator/(Type& type, Number n) { - type.setTime(type.getTime() / n); - return type; -} - -template<typename Type, typename Number> -Type& operator*(Type& type, Number n) { - type.setTime(type.getTime() * n); - return type; -} - -template<typename Type, int MPU> -std::ostream& operator<<(std::ostream& out, const Time<Type, MPU>& t); - -template<typename Type, int MPU> -vespalib::asciistream& operator<<(vespalib::asciistream& out, const Time<Type, MPU>& t); - -struct MicroSecTime; - -/** - * \class storage::framework::SecondTime - * \ingroup clock - * - * \brief Wrapper class for a timestamp in seconds. - * - * To prevent errors where one passes time in one granularity to a function - * requiring time in another granularity. This little wrapper class exist to - * make sure that will conflict in types - */ -struct SecondTime : public Time<SecondTime, 1000000> { - explicit SecondTime(uint64_t t = 0) : Time<SecondTime, 1000000>(t) {} - explicit SecondTime(const Clock& clock) - : Time<SecondTime, 1000000>(getRawMicroTime(clock) / 1000000) {} -}; - /** * \class storage::framework::MicroSecTime * \ingroup clock @@ -122,26 +19,29 @@ struct SecondTime : public Time<SecondTime, 1000000> { * requiring time in another granularity. This little wrapper class exist to * make sure that will conflict in types */ -struct MicroSecTime : public Time<MicroSecTime, 1> { - explicit MicroSecTime(uint64_t t = 0) : Time<MicroSecTime, 1>(t) {} - explicit MicroSecTime(const Clock& clock) - : Time<MicroSecTime, 1>(getRawMicroTime(clock)) {} +class MicroSecTime +{ +public: + explicit MicroSecTime(uint64_t t) noexcept : _time(t) {} - [[nodiscard]] SecondTime getSeconds() const { return SecondTime(getTime() / 1000000); } + [[nodiscard]] uint64_t getTime() const noexcept { return _time; } + + bool operator<(const MicroSecTime& o) const noexcept { return (_time < o._time); } + bool operator<=(const MicroSecTime& o) const noexcept { return (_time <= o._time); } + bool operator>=(const MicroSecTime& o) const noexcept { return (_time >= o._time); } + bool operator>(const MicroSecTime& o) const noexcept { return (_time > o._time); } + bool operator==(const MicroSecTime& o) const noexcept { return (_time == o._time); } + + [[nodiscard]] uint32_t getSeconds() const noexcept { return (getTime() / 1000000); } + + static MicroSecTime max() noexcept { return MicroSecTime(std::numeric_limits<uint64_t>::max()); } +private: + // time_t may be signed. Negative timestamps is just a source for bugs. Enforce unsigned. + uint64_t _time; }; -inline MicroSecTime -operator + (MicroSecTime a, MicroSecTime b) { - MicroSecTime result(a); - result += b; - return result; -} +std::ostream& operator<<(std::ostream& out, const MicroSecTime & t); -inline MicroSecTime -operator - (MicroSecTime a, MicroSecTime b) { - MicroSecTime result(a); - result -= b; - return result; -} +vespalib::asciistream& operator<<(vespalib::asciistream& out, const MicroSecTime & t); } diff --git a/storage/src/vespa/storageframework/generic/clock/time.hpp b/storage/src/vespa/storageframework/generic/clock/time.hpp deleted file mode 100644 index 2cc3fb7be9d..00000000000 --- a/storage/src/vespa/storageframework/generic/clock/time.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include "time.h" -#include <vespa/vespalib/stllike/asciistream.h> - -namespace storage { -namespace framework { - -template<typename Type, int MPU> -std::ostream& operator<<(std::ostream& out, const Time<Type, MPU>& t) { - return out << t.getTime(); -} - -template<typename Type, int MPU> -vespalib::asciistream& operator<<(vespalib::asciistream& out, const Time<Type, MPU>& t) { - return out << t.getTime(); -} - -} // framework -} // storage diff --git a/storage/src/vespa/storageframework/generic/clock/timer.h b/storage/src/vespa/storageframework/generic/clock/timer.h index 82b2fcc448e..aabef4601e0 100644 --- a/storage/src/vespa/storageframework/generic/clock/timer.h +++ b/storage/src/vespa/storageframework/generic/clock/timer.h @@ -14,7 +14,7 @@ namespace storage::framework { class MilliSecTimer { const Clock* _clock; - MonotonicTimePoint _startTime; + vespalib::steady_time _startTime; public: explicit MilliSecTimer(const Clock& clock) @@ -26,7 +26,7 @@ public: MilliSecTimer(const MilliSecTimer&) = default; MilliSecTimer& operator=(const MilliSecTimer&) = default; - [[nodiscard]] MonotonicDuration getElapsedTime() const { + [[nodiscard]] vespalib::duration getElapsedTime() const { return _clock->getMonotonicTime() - _startTime; } diff --git a/storageserver/src/apps/storaged/storage.cpp b/storageserver/src/apps/storaged/storage.cpp index d2a78657881..f3e8def6adf 100644 --- a/storageserver/src/apps/storaged/storage.cpp +++ b/storageserver/src/apps/storaged/storage.cpp @@ -121,7 +121,9 @@ namespace { void killHandler(int sig) { if (_G_signalCount == 0) { _G_signalCount++; - if (sigtramp == nullptr) _exit(EXIT_FAILURE); + if (sigtramp == nullptr) { + std::_Exit(EXIT_FAILURE); + } // note: this is not totally safe, sigtramp is not protected by a lock sigtramp->handleSignal(sig); } else if (_G_signalCount > 2) { diff --git a/storageserver/src/vespa/storageserver/app/distributorprocess.cpp b/storageserver/src/vespa/storageserver/app/distributorprocess.cpp index 7e65ff68601..987b3b613d8 100644 --- a/storageserver/src/vespa/storageserver/app/distributorprocess.cpp +++ b/storageserver/src/vespa/storageserver/app/distributorprocess.cpp @@ -5,6 +5,7 @@ #include <vespa/storage/common/bucket_stripe_utils.h> #include <vespa/storage/common/i_storage_chain_builder.h> #include <vespa/storage/common/storagelink.h> +#include <vespa/storageframework/defaultimplementation/clock/realclock.h> #include <thread> #include <vespa/log/log.h> @@ -14,7 +15,7 @@ namespace storage { DistributorProcess::DistributorProcess(const config::ConfigUri & configUri) : Process(configUri), - _context(), + _context(std::make_unique<framework::defaultimplementation::RealClock>()), _num_distributor_stripes(0), // TODO STRIPE: change default when legacy single stripe mode is removed _node(), _distributorConfigHandler(), diff --git a/storageserver/src/vespa/storageserver/app/servicelayerprocess.cpp b/storageserver/src/vespa/storageserver/app/servicelayerprocess.cpp index e6af40a552d..ab962fc78b2 100644 --- a/storageserver/src/vespa/storageserver/app/servicelayerprocess.cpp +++ b/storageserver/src/vespa/storageserver/app/servicelayerprocess.cpp @@ -6,6 +6,7 @@ #include <vespa/storage/common/i_storage_chain_builder.h> #include <vespa/storage/config/config-stor-server.h> #include <vespa/storage/storageserver/servicelayernode.h> +#include <vespa/storageframework/defaultimplementation/clock/realclock.h> #include <vespa/searchvisitor/searchvisitor.h> #include <vespa/log/log.h> diff --git a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp index 77da1693317..27442cab6ca 100644 --- a/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp +++ b/vespalib/src/tests/stllike/uniq_by_sort_map_hash.cpp @@ -28,7 +28,7 @@ public: }; RoundRobinAllocator() { } template<typename _Tp1> - RoundRobinAllocator(const RoundRobinAllocator<_Tp1>&) throw() { } + RoundRobinAllocator(const RoundRobinAllocator<_Tp1>&) noexcept { } void construct(pointer p, const T& val) { new(static_cast<void*>(p)) T(val); } void destroy(pointer p) { @@ -49,7 +49,7 @@ public: _r += n; } } - size_type max_size() const throw() { return _sz; } + size_type max_size() const noexcept { return _sz; } private: static size_t _r; diff --git a/vespalib/src/vespa/vespalib/util/time.cpp b/vespalib/src/vespa/vespalib/util/time.cpp index 2dbaade8c0a..51d5e580609 100644 --- a/vespalib/src/vespa/vespalib/util/time.cpp +++ b/vespalib/src/vespa/vespalib/util/time.cpp @@ -92,37 +92,3 @@ Timer::waitAtLeast(duration dur, bool busyWait) { } } - -#ifndef __clang__ - -namespace std::chrono { - -/* - * This is a hack to avoid the slow clock computations on RHEL7/CentOS 7 due to using systemcalls. - * This brings cost down from 550-560ns to 18-19ns on a Intel Haswell 2680 cpu. - * We are providing the symbols here so they will take precedence over the ones in the standard library. - * We rely on the linker do handle correct symbol resolution. - * TODO: Once we are off the ancient platforms like Centos 7/ Rhel 7 we can drop this workaround. -*/ - -inline namespace _V2 { - -system_clock::time_point -system_clock::now() noexcept { - timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); - return time_point(duration(chrono::seconds(tp.tv_sec) - + chrono::nanoseconds(tp.tv_nsec))); -} - -steady_clock::time_point -steady_clock::now() noexcept { - timespec tp; - clock_gettime(CLOCK_MONOTONIC, &tp); - return time_point(duration(chrono::seconds(tp.tv_sec) - + chrono::nanoseconds(tp.tv_nsec))); -} - -} -} -#endif diff --git a/vespalog/src/logger/llreader.h b/vespalog/src/logger/llreader.h index 1fadf2c6ae0..26d3bf3e4a5 100644 --- a/vespalog/src/logger/llreader.h +++ b/vespalog/src/logger/llreader.h @@ -12,8 +12,8 @@ private: public: MsgException(const MsgException &x) : std::exception(), _string(x._string) {} MsgException(const char *s) : _string(s) {} - ~MsgException() throw() {} // nothing to do - const char *what() const throw() override { return _string; } + ~MsgException() override = default; + const char *what() const noexcept override { return _string; } }; class InputBuf |