137 lines
2.8 KiB
C++
137 lines
2.8 KiB
C++
|
|
/// @file party/registry.cpp
|
||
|
|
#include "registry.hpp"
|
||
|
|
|
||
|
|
#include <algorithm>
|
||
|
|
#include <iostream>
|
||
|
|
#include <sstream>
|
||
|
|
#include <stdexcept>
|
||
|
|
|
||
|
|
namespace dpf
|
||
|
|
{
|
||
|
|
namespace party
|
||
|
|
{
|
||
|
|
namespace
|
||
|
|
{
|
||
|
|
|
||
|
|
std::vector<flow> & table()
|
||
|
|
{
|
||
|
|
static std::vector<flow> t;
|
||
|
|
return t;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::vector<std::string> split_csv(std::string_view s)
|
||
|
|
{
|
||
|
|
std::vector<std::string> out;
|
||
|
|
std::string cur;
|
||
|
|
for (char c : s)
|
||
|
|
{
|
||
|
|
if (c == ',' || c == ' ')
|
||
|
|
{
|
||
|
|
if (!cur.empty())
|
||
|
|
{
|
||
|
|
out.push_back(cur);
|
||
|
|
cur.clear();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
cur.push_back(c);
|
||
|
|
}
|
||
|
|
if (!cur.empty())
|
||
|
|
out.push_back(cur);
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
void register_flow(flow f)
|
||
|
|
{
|
||
|
|
if (f.name == nullptr || f.run == nullptr)
|
||
|
|
throw std::invalid_argument("register_flow: null name or run");
|
||
|
|
for (const auto & e : table())
|
||
|
|
{
|
||
|
|
if (e.name == f.name || std::string_view(e.name) == f.name)
|
||
|
|
throw std::invalid_argument(std::string("duplicate flow: ") + f.name);
|
||
|
|
}
|
||
|
|
table().push_back(f);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool flow_has_tag(const flow & f, std::string_view tag)
|
||
|
|
{
|
||
|
|
if (tag.empty())
|
||
|
|
return true;
|
||
|
|
if (f.tags == nullptr)
|
||
|
|
return false;
|
||
|
|
std::string_view tags(f.tags);
|
||
|
|
std::size_t i = 0;
|
||
|
|
while (i < tags.size())
|
||
|
|
{
|
||
|
|
while (i < tags.size() && tags[i] == ' ')
|
||
|
|
++i;
|
||
|
|
std::size_t j = i;
|
||
|
|
while (j < tags.size() && tags[j] != ' ')
|
||
|
|
++j;
|
||
|
|
if (j > i && tags.substr(i, j - i) == tag)
|
||
|
|
return true;
|
||
|
|
i = j;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool flow_is_pair(const flow & f)
|
||
|
|
{
|
||
|
|
const std::string_view name = f.name ? f.name : "";
|
||
|
|
if (name.size() >= 5 && name.substr(0, 5) == "iknp_")
|
||
|
|
return true;
|
||
|
|
return flow_has_tag(f, "iknp");
|
||
|
|
}
|
||
|
|
|
||
|
|
const flow * find_flow(std::string_view name)
|
||
|
|
{
|
||
|
|
for (const auto & f : table())
|
||
|
|
{
|
||
|
|
if (f.name == name)
|
||
|
|
return &f;
|
||
|
|
}
|
||
|
|
return nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::vector<const flow *> select_flows(std::string_view filter)
|
||
|
|
{
|
||
|
|
std::vector<const flow *> out;
|
||
|
|
auto want = split_csv(filter);
|
||
|
|
for (const auto & f : table())
|
||
|
|
{
|
||
|
|
bool ok = true;
|
||
|
|
for (const auto & t : want)
|
||
|
|
{
|
||
|
|
if (!flow_has_tag(f, t))
|
||
|
|
{
|
||
|
|
ok = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (ok)
|
||
|
|
out.push_back(&f);
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
void list_flows(std::ostream & os, std::string_view filter)
|
||
|
|
{
|
||
|
|
auto sel = select_flows(filter);
|
||
|
|
for (const flow * f : sel)
|
||
|
|
{
|
||
|
|
os << f->name << '\t' << (f->tags ? f->tags : "")
|
||
|
|
<< (f->bench ? "\tbench" : "\tsmoke") << '\n';
|
||
|
|
}
|
||
|
|
os << "# " << sel.size() << " flows\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
std::size_t flow_count()
|
||
|
|
{
|
||
|
|
return table().size();
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace party
|
||
|
|
} // namespace dpf
|