Unverified Commit 595fca4d authored by Stephan Lachnit's avatar Stephan Lachnit
Browse files

[v2.3-stable] Fix instance overwriting



(cherry picked from commit dde9a5be)

Signed-off-by: default avatarStephan Lachnit <stephanlachnit@debian.org>
parent 0cbd9015
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -159,26 +159,25 @@ std::list<Configuration>& ConfigManager::getDetectorConfigurations() {
/**
 * @warning A previously stored configuration is directly invalidated if the same unique name is used again
 *
 * An instance configuration is a specialized configuration for a particular module instance. If an unique name already
 * exists the previous record is deleted and a new configuration record corresponding to the replaced instance is added.
 * An instance configuration is a specialized configuration for a particular module instance. If a ModuleIdentifier already
 * exists an error is thrown.
 */
Configuration& ConfigManager::addInstanceConfiguration(const ModuleIdentifier& identifier, const Configuration& config) {
    std::string unique_name = identifier.getUniqueName();
    // Check uniqueness
    if(instance_name_to_config_.find(unique_name) != instance_name_to_config_.end()) {
        instance_configs_.erase(instance_name_to_config_[unique_name]);
    if(instance_identifier_to_config_.find(identifier) != instance_identifier_to_config_.end()) {
        throw ModuleIdentifierAlreadyAddedError(identifier);
    }

    // Add configuration
    instance_configs_.push_back(config);
    Configuration& ret_config = instance_configs_.back();
    instance_name_to_config_[unique_name] = --instance_configs_.end();
    instance_identifier_to_config_[identifier] = --instance_configs_.end();

    // Add identifier key to config
    ret_config.set<std::string>("identifier", identifier.getIdentifier());

    // Apply instance options
    module_option_parser_.applyOptions(unique_name, ret_config);
    module_option_parser_.applyOptions(identifier.getUniqueName(), ret_config);
    return ret_config;
}

@@ -189,3 +188,18 @@ Configuration& ConfigManager::addInstanceConfiguration(const ModuleIdentifier& i
std::list<Configuration>& ConfigManager::getInstanceConfigurations() {
    return instance_configs_;
}

/**
 * An instance configuration might be dropped when not used (e.g. it is overwritten by another module instance afterwards)
 * We need to remove it from the instance configuration list to ensure dumping the config actually dumps only the instance
 * configurations that were used.
 */
void ConfigManager::dropInstanceConfiguration(const ModuleIdentifier& identifier) {
    // Remove config from instance configs and from instance identifier map
    if(instance_identifier_to_config_.find(identifier) != instance_identifier_to_config_.end()) {
        instance_configs_.erase(instance_identifier_to_config_[identifier]);
        instance_identifier_to_config_.erase(identifier);
    } else {
        throw ModuleIdentifierNotFoundError(identifier);
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -89,6 +89,12 @@ namespace allpix {
         */
        std::list<Configuration>& getInstanceConfigurations();

        /**
         * @brief Drops an instance configuration from instance configuration storage
         * @param identifier Identifier of the module instance to drop
         */
        void dropInstanceConfiguration(const ModuleIdentifier& identifier);

        /**
         * @brief Load module options and directly apply them to the global configuration and the module configurations
         * @param options List of options to load and apply
@@ -124,7 +130,7 @@ namespace allpix {
        std::list<Configuration> detector_configs_;

        std::list<Configuration> instance_configs_;
        std::map<std::string, std::list<Configuration>::iterator> instance_name_to_config_;
        std::map<ModuleIdentifier, std::list<Configuration>::iterator> instance_identifier_to_config_;
    };
} // namespace allpix

+11 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@

#include "core/config/exceptions.h"
#include "Configuration.hpp"
#include "core/module/ModuleIdentifier.hpp"

using namespace allpix;

@@ -43,3 +44,13 @@ InvalidCombinationError::InvalidCombinationError(const Configuration& config,
        error_message_ += ": " + reason;
    }
}

ModuleIdentifierNotFoundError::ModuleIdentifierNotFoundError(const ModuleIdentifier& identifier) {
    error_message_ = "Module Identifier " + identifier.getUniqueName() + ":" + std::to_string(identifier.getPriority()) +
                     " not found in the module identifier list";
}

ModuleIdentifierAlreadyAddedError::ModuleIdentifierAlreadyAddedError(const ModuleIdentifier& identifier) {
    error_message_ = "Module Identifier " + identifier.getUniqueName() + ":" + std::to_string(identifier.getPriority()) +
                     " already added to the module identifier list";
}
+18 −0
Original line number Diff line number Diff line
@@ -168,6 +168,24 @@ namespace allpix {
                                std::initializer_list<std::string> keys,
                                const std::string& reason = "");
    };

    class ModuleIdentifier;
    /**
     * @ingroup Exceptions
     * @brief Indicates that a given ModuleIdentifier was not found in the module identifier list
     */
    class ModuleIdentifierNotFoundError : public LogicError {
    public:
        explicit ModuleIdentifierNotFoundError(const ModuleIdentifier& identifier);
    };
    /**
     * @ingroup Exceptions
     * @brief Indicates that a given ModuleIdentifier is already in the module identifier list
     */
    class ModuleIdentifierAlreadyAddedError : public LogicError {
    public:
        explicit ModuleIdentifierAlreadyAddedError(const ModuleIdentifier& identifier);
    };
} // namespace allpix

#endif /* ALLPIX_CONFIG_EXCEPTIONS_H */
+23 −7
Original line number Diff line number Diff line
@@ -73,14 +73,30 @@ namespace allpix {
        /**
         * @brief Operators for comparing identifiers
         *
         * Identifiers are only compared on their unique name, identifiers are not distinguished on priorities
         * Identifiers are compared on their unique name and their priorities
         */
        bool operator==(const ModuleIdentifier& other) const { return getUniqueName() == other.getUniqueName(); }
        bool operator!=(const ModuleIdentifier& other) const { return getUniqueName() != other.getUniqueName(); }
        bool operator<(const ModuleIdentifier& other) const { return getUniqueName() < other.getUniqueName(); }
        bool operator<=(const ModuleIdentifier& other) const { return getUniqueName() <= other.getUniqueName(); }
        bool operator>(const ModuleIdentifier& other) const { return getUniqueName() > other.getUniqueName(); }
        bool operator>=(const ModuleIdentifier& other) const { return getUniqueName() >= other.getUniqueName(); }
        bool operator==(const ModuleIdentifier& other) const {
            return getUniqueName() == other.getUniqueName() && getPriority() == other.getPriority();
        }
        bool operator!=(const ModuleIdentifier& other) const {
            return getUniqueName() != other.getUniqueName() || getPriority() != other.getPriority();
        }
        bool operator<(const ModuleIdentifier& other) const {
            return getUniqueName() != other.getUniqueName() ? getUniqueName() < other.getUniqueName()
                                                            : getPriority() < other.getPriority();
        }
        bool operator<=(const ModuleIdentifier& other) const {
            return getUniqueName() != other.getUniqueName() ? getUniqueName() <= other.getUniqueName()
                                                            : getPriority() <= other.getPriority();
        }
        bool operator>(const ModuleIdentifier& other) const {
            return getUniqueName() != other.getUniqueName() ? getUniqueName() > other.getUniqueName()
                                                            : getPriority() > other.getPriority();
        }
        bool operator>=(const ModuleIdentifier& other) const {
            return getUniqueName() != other.getUniqueName() ? getUniqueName() >= other.getUniqueName()
                                                            : getPriority() >= other.getPriority();
        }
        /// @}

    private:
Loading