Я обрабатываю большие файлы, состоящие из множества избыточных значений (используя якоря и ссылки YAML). Обработка, которую я выполняю для каждой структуры, является дорогой, и я хотел бы определить, смотрю ли я на ссылку на якорь, который я уже обработал. В Python (с python-yaml) я сделал это, просто создав словарь с ключом id (node). Однако, поскольку yaml-cpp использует Node в качестве ссылочного типа, здесь это, похоже, не работает. Какие-либо предложения?
Это похоже на Получить якорь & строка псевдонима в yaml-cpp из документа, но хотя этой функции было бы достаточно для решения моей проблемы, она не является необходимой — если бы я мог каким-то образом получить хэш, например, на основе внутреннего адреса узла, это было бы хорошо.
Дорогая вещь, которую я делаю, это вычисление хэша каждого узла, включая его самого и его дочерних элементов.
Вот патч, который, кажется, делает то, что мне нужно. Действовать с осторожностью.
diff -nr include/yaml-cpp/node/detail/node.h new/yaml-cpp-0.5.1/include/yaml-cpp/node/detail/node.h
a13 1
#include <boost/functional/hash.hpp>
a24 1
std::size_t identity_hash() const { return boost::hash<node_ref*>()(m_pRef.get()); }
diff -nr /include/yaml-cpp/node/impl.h new/yaml-cpp-0.5.1/include/yaml-cpp/node/impl.h
a175 5
inline std::size_t Node::identity_hash() const
{
return m_pNode->identity_hash();
}
diff -nr include/yaml-cpp/node/node.h new/yaml-cpp-0.5.1/include/yaml-cpp/node/node.h
a55 2
std::size_t identity_hash() const;
Затем я могу использовать приведенное ниже, чтобы создать unordered_map, используя YAML :: Node в качестве ключа.
namespace std {
template <>
struct hash<YAML::Node> {
size_t operator()(const YAML::Node& ss) const {
return ss.identity_hash();
}
};
}
Вы можете проверить идентичность узла, operator ==
или же Node::is
Например:
Node a = ...;
process(a);
Node b = ...;
if (!a.is(b)) {
process(b);
}
Я предполагаю, что это не идеально — если вы пытаетесь сделать это на большом списке узлов, проверка должна быть O (n).
Если вы хотите большего, пожалуйста, сообщите о проблеме на странице проекта.