Skip to content

Commit a4809ef

Browse files
committed
(cont)
1 parent d4cb58d commit a4809ef

File tree

3 files changed

+75
-45
lines changed

3 files changed

+75
-45
lines changed

src/flow/log/config.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
# define FLOW_LOG_CONFIG_COMPONENT_PAYLOAD_TYPE_DICT_BY_PTR Component_payload_type_dict_by_ptr_via_s_hash_map
8181
# endif
8282
# ifndef FLOW_LOG_CONFIG_COMPONENT_PAYLOAD_TYPE_DICT_BY_VAL
83-
# define FLOW_LOG_CONFIG_COMPONENT_PAYLOAD_TYPE_DICT_BY_VAL Component_payload_type_dict_by_val_via_sorted_array
83+
# define FLOW_LOG_CONFIG_COMPONENT_PAYLOAD_TYPE_DICT_BY_VAL Component_payload_type_dict_by_val_via_array
8484
# endif
8585
#endif // if !defined(FLOW_DOXYGEN_ONLY)
8686

src/flow/log/detail/test/component_cfg_test.cpp

Lines changed: 73 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
* See the License for the specific language governing
1616
* permissions and limitations under the License. */
1717

18-
#include "flow/log/detail/component_cfg.hpp"
1918
#include "flow/log/log.hpp"
19+
#include "flow/log/simple_ostream_logger.hpp"
20+
#include "flow/log/detail/component_cfg.hpp" // Yes, detail/ -- we do what we must.
2021
#include "flow/test/test_logger.hpp"
2122
#include "flow/perf/checkpt_timer.hpp"
2223
#include "flow/util/string_view.hpp"
@@ -50,17 +51,18 @@ using Dict_val_b_hash_map = Component_payload_type_dict_by_val_via_b_hash_map<cf
5051
using Dict_val_array = Component_payload_type_dict_by_val_via_array<cfg_t>;
5152
using Dict_val_sorted_array = Component_payload_type_dict_by_val_via_sorted_array<cfg_t>;
5253

53-
namespace n1::n1 { enum class Enum { S_A }; }
54-
namespace n2::n2 { enum class Enum { S_A }; }
55-
namespace n3::n3 { enum class Enum { S_A }; }
56-
namespace n4::n4 { enum class Enum { S_A }; }
57-
namespace n5::n5 { enum class Enum { S_A }; }
58-
namespace n6::n6 { enum class Enum { S_A }; }
59-
namespace n7::n7 { enum class Enum { S_A }; }
60-
namespace n8::n8 { enum class Enum { S_A }; }
61-
namespace n9::n9 { enum class Enum { S_A }; }
62-
namespace n0::n0 { enum class Enum { S_A }; }
63-
namespace nX::nX { enum class Enum { S_A }; }
54+
namespace n1::n1 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
55+
namespace n2::n2 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
56+
namespace n3::n3 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
57+
namespace n4::n4 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
58+
namespace n5::n5 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
59+
namespace n6::n6 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
60+
namespace n7::n7 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
61+
namespace n8::n8 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
62+
namespace n9::n9 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
63+
namespace n0::n0 { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
64+
namespace nX::nX { enum class Cmps : Component::enum_raw_t { S_COMP_A, S_COMP_B }; }
65+
constexpr auto S_CMPS_SZ = static_cast<Component::enum_raw_t>(nX::nX::Cmps::S_COMP_B) + 1;
6466

6567
String_view dict_type_printable(const std::type_index& type, bool brief = false)
6668
{
@@ -108,16 +110,16 @@ void dict_map_death_test()
108110
{
109111
FLOW_LOG_INFO("Testing dict-type [" << dict_type_printable(typeid(Dict)) << "].");
110112
Dict dict;
111-
dict.insert(typeid(n1::n1::Enum), 1);
112-
dict.insert(typeid(n0::n0::Enum), 0);
113-
EXPECT_DEATH(dict.insert(typeid(n0::n0::Enum), 0), "duplicate insertion is disallowed");
114-
EXPECT_DEATH(dict.insert(typeid(n0::n0::Enum), -1), "duplicate insertion is disallowed");
115-
dict.insert(typeid(n2::n2::Enum), 2);
113+
dict.insert(typeid(n1::n1::Cmps), 1);
114+
dict.insert(typeid(n0::n0::Cmps), 0);
115+
EXPECT_DEATH(dict.insert(typeid(n0::n0::Cmps), 0), "duplicate insertion is disallowed");
116+
EXPECT_DEATH(dict.insert(typeid(n0::n0::Cmps), -1), "duplicate insertion is disallowed");
117+
dict.insert(typeid(n2::n2::Cmps), 2);
116118
cfg_t cfg;
117-
EXPECT_TRUE(dict.lookup(typeid(n0::n0::Enum), &cfg)); // Sanity checks.
118-
EXPECT_TRUE(dict.lookup(typeid(n1::n1::Enum), &cfg));
119-
EXPECT_TRUE(dict.lookup(typeid(n2::n2::Enum), &cfg));
120-
EXPECT_FALSE(dict.lookup(typeid(n3::n3::Enum), &cfg));
119+
EXPECT_TRUE(dict.lookup(typeid(n0::n0::Cmps), &cfg)); // Sanity checks.
120+
EXPECT_TRUE(dict.lookup(typeid(n1::n1::Cmps), &cfg));
121+
EXPECT_TRUE(dict.lookup(typeid(n2::n2::Cmps), &cfg));
122+
EXPECT_FALSE(dict.lookup(typeid(n3::n3::Cmps), &cfg));
121123
})(), ...);
122124
}
123125

@@ -132,24 +134,24 @@ void dict_test()
132134
FLOW_LOG_INFO("Testing dict-type [" << dict_type_printable(typeid(Dict)) << "].");
133135
{
134136
Dict dict;
135-
dict.insert(typeid(n1::n1::Enum), 1);
136-
dict.insert(typeid(n0::n0::Enum), 0);
137-
dict.insert(typeid(n2::n2::Enum), 2);
138-
dict.insert(typeid(nX::nX::Enum), 100);
137+
dict.insert(typeid(n1::n1::Cmps), 1);
138+
dict.insert(typeid(n0::n0::Cmps), 0);
139+
dict.insert(typeid(n2::n2::Cmps), 2);
140+
dict.insert(typeid(nX::nX::Cmps), 100);
139141
cfg_t cfg{-1};
140-
EXPECT_FALSE(dict.lookup(typeid(n3::n3::Enum), &cfg));
142+
EXPECT_FALSE(dict.lookup(typeid(n3::n3::Cmps), &cfg));
141143
EXPECT_EQ(cfg, -1);
142-
EXPECT_TRUE(dict.lookup(typeid(n0::n0::Enum), &cfg));
144+
EXPECT_TRUE(dict.lookup(typeid(n0::n0::Cmps), &cfg));
143145
EXPECT_EQ(cfg, 0);
144-
EXPECT_TRUE(dict.lookup(typeid(n1::n1::Enum), &cfg));
146+
EXPECT_TRUE(dict.lookup(typeid(n1::n1::Cmps), &cfg));
145147
EXPECT_EQ(cfg, 1);
146-
EXPECT_TRUE(dict.lookup(typeid(n2::n2::Enum), &cfg));
148+
EXPECT_TRUE(dict.lookup(typeid(n2::n2::Cmps), &cfg));
147149
EXPECT_EQ(cfg, 2);
148-
EXPECT_FALSE(dict.lookup(typeid(n3::n3::Enum), &cfg));
150+
EXPECT_FALSE(dict.lookup(typeid(n3::n3::Cmps), &cfg));
149151
EXPECT_EQ(cfg, 2);
150-
EXPECT_TRUE(dict.lookup(typeid(n0::n0::Enum), &cfg));
152+
EXPECT_TRUE(dict.lookup(typeid(n0::n0::Cmps), &cfg));
151153
EXPECT_EQ(cfg, 0);
152-
EXPECT_TRUE(dict.lookup(typeid(nX::nX::Enum), &cfg));
154+
EXPECT_TRUE(dict.lookup(typeid(nX::nX::Cmps), &cfg));
153155
EXPECT_EQ(cfg, 100);
154156
/* @todo It is tough to test _by_val_ dudes where &typeid(X) yields different addrs at different times;
155157
* probably needs to be done across a shared-object boundary at least. Could contrive something though.
@@ -164,7 +166,7 @@ void dict_test()
164166
{
165167
Dict dict; // Deal with degenerate case of an empty dict.
166168
cfg_t cfg{-1};
167-
EXPECT_FALSE(dict.lookup(typeid(n0::n0::Enum), &cfg));
169+
EXPECT_FALSE(dict.lookup(typeid(n0::n0::Cmps), &cfg));
168170
EXPECT_EQ(cfg, -1);
169171
}
170172
})(), ...);
@@ -191,18 +193,21 @@ void dict_benchmark(size_t n_cfgs)
191193
struct Type_rec { Ti m_type; cfg_t m_cfg; };
192194
vector<Type_rec> all_types =
193195
{
194-
Type_rec{ &typeid(n1::n1::Enum), 1 }, Type_rec{ &typeid(n2::n2::Enum), 2 },
195-
Type_rec{ &typeid(n3::n3::Enum), 3 }, Type_rec{ &typeid(n4::n4::Enum), 4 },
196-
Type_rec{ &typeid(n5::n5::Enum), 5 }, Type_rec{ &typeid(n6::n6::Enum), 6 },
197-
Type_rec{ &typeid(n7::n7::Enum), 7 }, Type_rec{ &typeid(n8::n8::Enum), 8 },
198-
Type_rec{ &typeid(n9::n9::Enum), 9 }, Type_rec{ &typeid(n0::n0::Enum), 0 }
196+
Type_rec{ &typeid(n1::n1::Cmps), 1 }, Type_rec{ &typeid(n2::n2::Cmps), 2 },
197+
Type_rec{ &typeid(n3::n3::Cmps), 3 }, Type_rec{ &typeid(n4::n4::Cmps), 4 },
198+
Type_rec{ &typeid(n5::n5::Cmps), 5 }, Type_rec{ &typeid(n6::n6::Cmps), 6 },
199+
Type_rec{ &typeid(n7::n7::Cmps), 7 }, Type_rec{ &typeid(n8::n8::Cmps), 8 },
200+
Type_rec{ &typeid(n9::n9::Cmps), 9 }, Type_rec{ &typeid(n0::n0::Cmps), 0 }
199201
};
200202
EXPECT_TRUE(n_cfgs <= all_types.size());
201203
all_types.resize(n_cfgs);
202204

203205
std::random_device rd; // Seed source.
204206
std::mt19937 gen(rd());
205207
std::uniform_int_distribution<size_t> dist_to_n_cfgs(0, n_cfgs - 1);
208+
perf::Clock_types_subset clocks;
209+
constexpr auto CLK_TYPE = size_t(perf::Clock_type::S_CPU_THREAD_TOTAL_HI_RES);
210+
clocks.set(CLK_TYPE);
206211

207212
/* Maps Dict_* type to total (findable lookup + unfindable lookup) benchmark result for that dictionary impl.
208213
* Note: Empirically we see (as of this writing in the ~3 types of hardware tried) that the failed-lookup and
@@ -229,7 +234,7 @@ void dict_benchmark(size_t n_cfgs)
229234
{
230235
std::shuffle(all_types.begin(), all_types.end(), gen);
231236

232-
const Ti unfindable_type = &typeid(nX::nX::Enum);
237+
const Ti unfindable_type = &typeid(nX::nX::Cmps);
233238
const auto& findable_type_rec = all_types[dist_to_n_cfgs(gen)];
234239
const Ti findable_type = findable_type_rec.m_type;
235240
const auto findable_cfg = findable_type_rec.m_cfg;
@@ -242,7 +247,7 @@ void dict_benchmark(size_t n_cfgs)
242247
dict.insert(*type.m_type, type.m_cfg);
243248
}
244249

245-
const auto timer = boost::make_shared<Timer>(nullptr, "benchiez", Timer::real_clock_types(), 2);
250+
const auto timer = boost::make_shared<Timer>(nullptr, "benchiez", clocks, 2);
246251
dict.lookup(*unfindable_type, &cfg_found1);
247252
timer->checkpoint("unfindable");
248253
dict.lookup(*findable_type, &cfg_found2);
@@ -262,7 +267,6 @@ void dict_benchmark(size_t n_cfgs)
262267
#endif
263268
// We can print out a pithy thing ourselves. (Also see above re. why we choose to use the sum.)
264269
const auto total_timer = timer_agg.create_aggregated_result(nullptr, false, 1);
265-
constexpr auto CLK_TYPE = size_t(perf::Clock_type::S_REAL_HI_RES);
266270
const Fine_duration time = total_timer->since_start().m_values[CLK_TYPE];
267271
const Fine_duration time1 = total_timer->checkpoints()[0].m_since_last.m_values[CLK_TYPE];
268272
#if 0 // We'll summarize even more pithily below by showing: (time) = (time1) + (time - time1).
@@ -447,9 +451,35 @@ TEST(Component_cfg_test, Dict_internals_benchmark)
447451
}
448452
}
449453

454+
/* While Dict_internals_interface tests the nitty-gritty of the map lookup at the heart of it -- which due to
455+
* perf matters has much subtlety to it -- this tests it end-to-end through the publicly available log::Config API. */
450456
TEST(Component_cfg_test, Interface)
451457
{
452-
// @todo Add.
453-
}
458+
#if 0
459+
Config cfg(Sev::S_INFO);
460+
cfg.init_component_to_union_idx_mapping<>
461+
(10,
462+
S_CMPS_SZ, // @todo Test subtleties of this arg.
463+
true);
464+
465+
Component comp0a{n0::n0::Cmps::S_COMP_A};
466+
Component comp0b{n0::n0::Cmps::S_COMP_B};
467+
Component comp1a{n1::n1::Cmps::S_COMP_A};
468+
Component comp1b{n1::n1::Cmps::S_COMP_B};
469+
454470

471+
472+
473+
/* @todo Test component names (config via component-name Config::configure_component_verbosity_by_name();
474+
* output of component-names Config::output_component_to_ostream(); the relevant Config::init_*()).
475+
* (Originally unit-test was created in the first place due to the Component_payload_type_dict_... work;
476+
* but as of this writing the other aspects of per-component log::Config remain un-unit-tested, though they
477+
* have long been verified via heavy use + functional tests. Obv the point of unit tests = do better than that.) */
478+
479+
/* @todo Test various `Logger`s and/or Ostream_log_msg_writer in the sense that they leverage component-based
480+
* log::Config aspects. I.e., test from a still-higher layer. Possibly that would go in the unit tests
481+
* for those classes though. As of this writing they don't exist. */
482+
#endif
483+
484+
} // TEST(Component_cfg_test, Interface)
455485
} // namespace flow::log::test

src/flow/log/ostream_log_msg_writer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ void Ostream_log_msg_writer::do_log_with_human_friendly_time_stamp(const Msg_met
140140
* @todo Maybe there is some way to just force it to print full-precision m_called_when in local time zone?
141141
* (boost.chrono did it, with a switch that would cause it to use either local time zone or UTC in the output;
142142
* but we are not using boost.chrono output anymore for perf reasons; plus one cannot specify a format
143-
* which is a nice feature we can use to expand Ostream_log_writer capabilities in the future.) */
143+
* which is a nice feature we can use to expand Ostream_log_msg_writer capabilities in the future.) */
144144
const auto end = fmt::format_to(m_last_human_friendly_time_stamp_str.begin(),
145145
static_cast<const std::string_view&>(TIME_STAMP_FORMAT),
146146
fmt::localtime(system_clock::to_time_t(metadata.m_called_when)),

0 commit comments

Comments
 (0)