Program Listing for File metadata.hpp
↰ Return to documentation for file (include/holoscan/core/metadata.hpp
)
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HOLOSCAN_CORE_METADATA_HPP
#define HOLOSCAN_CORE_METADATA_HPP
#include <memory>
#include <shared_mutex>
#include <string>
#include <typeinfo>
#include <unordered_map>
#include <utility>
#include <vector>
#include "./codec_registry.hpp"
#include "./common.hpp"
#include "./message.hpp"
using std::string_literals::operator""s;
namespace holoscan {
// reuse holoscan::Message so same serialization codecs can be reused for metadata
using MetadataObject = holoscan::Message;
enum class MetadataPolicy {
kReject,
kInplaceUpdate,
kUpdate,
kRaise,
};
class MetadataDictionary {
public:
using MapType = std::unordered_map<std::string, std::shared_ptr<MetadataObject>>;
using Iterator = MapType::iterator;
using ConstIterator = MapType::const_iterator;
// Constructors
explicit MetadataDictionary(const MetadataPolicy& policy = MetadataPolicy::kUpdate)
: dictionary_(std::make_shared<MapType>()), policy_(policy) {}
MetadataDictionary(const MetadataDictionary&) = default;
MetadataDictionary(MetadataDictionary&&) = default;
// assignment operators
MetadataDictionary& operator=(const MetadataDictionary&);
MetadataDictionary& operator=(MetadataDictionary&&) = default;
// Destructor
virtual ~MetadataDictionary() = default;
std::vector<std::string> keys() const;
std::shared_ptr<MetadataObject>& operator[](const std::string&);
const MetadataObject* operator[](const std::string&) const;
std::shared_ptr<MetadataObject> get(const std::string& key) const;
template <typename ValueT>
ValueT get(const std::string& key) const {
auto it = dictionary_->find(key);
if (it == dictionary_->end()) {
throw std::runtime_error(fmt::format("Key '{}' does not exist", key));
}
const auto& shared_obj = it->second;
return std::any_cast<ValueT>(shared_obj->value());
}
template <typename ValueT>
ValueT get(const std::string& key, const ValueT& default_value) const {
auto it = dictionary_->find(key);
if (it == dictionary_->end()) { return default_value; }
const auto& shared_obj = it->second;
return std::any_cast<ValueT>(shared_obj->value());
}
void set(const std::string& key, std::shared_ptr<MetadataObject> value);
template <typename ValueT, typename = std::enable_if_t<!std::is_same_v<
std::decay_t<ValueT>, std::shared_ptr<MetadataObject>>>>
void set(const std::string& key, ValueT value) {
ensure_unique();
auto it = dictionary_->find(key);
if (it == dictionary_->end()) {
(*dictionary_)[key] = std::make_shared<MetadataObject>(value);
} else {
switch (policy_) {
case MetadataPolicy::kReject:
// keep the old value
break;
case MetadataPolicy::kInplaceUpdate:
// set the std::any member within the existing MetadataObject
(it->second)->set_value(value);
break;
case MetadataPolicy::kUpdate:
// replace the MetadataObject with a newly constructed one
(*dictionary_)[key] = std::make_shared<MetadataObject>(value);
break;
case MetadataPolicy::kRaise:
throw std::runtime_error(
fmt::format("Key '{}' already exists. The application should be updated to avoid "
"duplicate metadata keys or a different holoscan::MetadataPolicy should "
"be set",
key));
default:
// Handle unknown policy
throw std::runtime_error("Unknown metadata policy");
}
return;
}
}
MetadataPolicy policy() const { return policy_; }
void policy(const MetadataPolicy& metadata_policy) { policy_ = metadata_policy; }
bool has_key(const std::string& key) const;
bool erase(const std::string& key);
Iterator begin();
ConstIterator begin() const;
Iterator end();
ConstIterator end() const;
Iterator find(const std::string& key);
ConstIterator find(const std::string& key) const;
void clear();
std::size_t size() const;
void swap(MetadataDictionary& other);
void merge(MetadataDictionary& other);
void insert(MetadataDictionary& other);
void update(MetadataDictionary& other);
private:
bool ensure_unique();
std::shared_ptr<MapType> dictionary_{};
MetadataPolicy policy_{MetadataPolicy::kUpdate};
};
} // namespace holoscan
#endif/* HOLOSCAN_CORE_METADATA_HPP */