ATLAS Offline Software
Loading...
Searching...
No Matches
TrigConfHLTUtils/Root/HLTUtils.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <iostream>
6#include <sstream>
7#include <stdexcept>
8#include <string>
9#include <algorithm>
10#include <iterator>
11#include <fstream>
12
14
15using namespace TrigConf;
16
17
20
23
24
25HLTHash HLTUtils::string2hash( const std::string& s, const std::string& category )
26{
27 // Try to find existing hash in category
28 const auto icat = s_hashStore.hashCat.find(category);
29 if (icat != s_hashStore.hashCat.end()) { // category found
30 const HashMap& cat = icat->second;
31 const auto ihash = cat.name2hash.find(s);
32 if (ihash != cat.name2hash.end()) { // hash found
33 return ihash->second;
34 }
35 }
36 else {
37 s_hashStore.hashCat.emplace(category, std::make_unique<HashMap>());
38 }
39
40 /*********************************************************************
41 This hash function is derived from the ELF hashing function and
42 unchanged since Run-1. For Phase-II we should really switch to a
43 64 bit hash like CxxUtils::crc64 which is safer (and faster).
44 But we need to take care of backwards compatibility with old data.
45 Original author: Tomasz Bold
46 *********************************************************************/
47 HLTHash hash = 0xd2d84a61;
48 for ( int i = (int)s.size()-1; i >= 0; --i )
49 hash ^= ( hash >> 5) + s[i] + ( hash << 7 );
50
51 for ( int i = 0; i < (int)s.size(); ++i )
52 hash ^= ( hash >> 5) + s[i] + ( hash << 7 );
53 /********************************************************************/
54
55 // Try to insert new hash
56 HashMap& cat = s_hashStore.hashCat.at(category);
57 const auto& [itr, inserted] = cat.hash2name.emplace(hash, s);
58
59 if ( inserted ) {
60 // also update reverse map
61 cat.name2hash.emplace(s, hash);
62 }
63 else {
64 // There are two cases where insertion into the hash->name map would fail:
65 // 1) another thread entered the same hash/name pair already
66 // 2) there is a hash collision
67 if ( s != itr->second ) {
68 throw std::domain_error("Hash collision in category " + category +
69 " for elements " + itr->second + " and " + s);
70 }
71 }
72
73 return hash;
74}
75
76const std::string HLTUtils::hash2string( HLTHash hash, const std::string& category ) {
77
78 const auto& icat = s_hashStore.hashCat.find(category);
79 if (icat == s_hashStore.hashCat.end()) {
80 return "UNKNOWN CATEGORY";
81 }
82
83 const HashMap& cat = icat->second;
84 const auto& h = cat.hash2name.find(hash);
85 if (h == cat.hash2name.end()) {
86 return "UNKNOWN HASH ID";
87 }
88
89 return h->second;
90}
91
92void HLTUtils::hashes2file( const std::string& fileName) {
93 std::ofstream fout(fileName);
94
95 for (const auto [category, hashes] : s_hashStore.hashCat) {
96 fout << s_newCategory << std::endl << category << std::endl;
97 for (const auto [hash, nameptr] : hashes.hash2name) {
98 std::string name(nameptr);
99 name.erase(std::remove(name.begin(), name.end(), '\n'), name.end()); // Remove any line breaks
100 fout << hash << std::endl << name << std::endl;
101 }
102 }
103}
104
105void HLTUtils::file2hashes( const std::string& fileName) {
106 std::ifstream fin(fileName);
107 if (!fin.is_open()) {
108 return;
109 }
110 std::string line;
111 std::string category;
112 // Note: this method is a to aid with development/debugging.
113 // It won't be used in production code, hence it is light on error checking.
114 while(std::getline(fin, line)) {
115 if (line == s_newCategory) {
116 std::getline(fin, category);
117 continue;
118 }
119 HLTHash hash = std::stoul(line);
120 std::string name;
121 std::getline(fin, name);
122 HLTHash check = string2hash(name, category);
123 if (check != hash) {
124 std::cerr << "Inconsistency in file2hashes(" << fileName << ") function,"
125 " item " << name << " has hash " << hash << " not " << check << std::endl;
126 }
127 }
128}
const_iterator find(const key_type &key) const
Look up an element in the map.
const_iterator end() const
Iterator at the end of the map.
std::pair< const_iterator, bool > emplace(key_type key, const mapped_type &val, const Context_t &ctx=Updater_t::defaultContext())
Add an element to the map.
const_iterator find(const key_type key) const
Look up an element in the map.
const_iterator end() const
Iterator at the end of the map.
static const std::string hash2string(HLTHash, const std::string &category="TE")
hash function translating identifiers into names (via internal dictionary)
static void hashes2file(const std::string &fileName="hashes2string.txt")
debugging output of internal dictionary
static const std::string s_newCategory
In-file identifier.
static HLTHash string2hash(const std::string &, const std::string &category="TE")
hash function translating TE names into identifiers
static void file2hashes(const std::string &fileName="hashes2string.txt")
debugging output of internal dictionary
static TFile * fout
Definition listroot.cxx:40
Forward iterator to traverse the main components of the trigger configuration.
Definition Config.h:22
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.
Two concurrent maps to store name->hash and hash->name mappings.
Hash2NameMap_t hash2name
hash to name map
Name2HashMap_t name2hash
name to hash map