#ifndef __M_ROUTE_H_
#define __M_ROUTE_H_
#include <iostream>
#include "../mqcommon/"
#include "../mqcommon/"
#include "../mqcommon/"
namespace mymq
{
class Router
{
public:
static bool isLegalRoutingKey(const std::string& routing_key)
{
// routing_key: There is no need to determine whether there are illegal characters, legal characters (a ~ z, A ~ Z,0 ~ 9, ....)
for(auto& ch : routing_key)
{
if((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch >= '1' && ch <= '9') ||
(ch == '_' || ch == '.'))
continue;
return false;
}
return true;
}
static bool isLegalBindingKey(const std::string& binding_key)
{
for(auto& ch : binding_key)
{
if((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') ||
(ch >= '1' && ch <= '9') ||
(ch == '_' || ch == '.') ||
(ch == '#' || ch == '*'))
continue;
return false;
}
// 2. *and # must exist independently
std::vector<std::string> sub_word;
StrHelper::split(binding_key, ".", sub_word);
for(std::string& word : sub_word)
{
if((word.size() > 1) && (("*") != std::string::npos && (("#") != std::string::npos)))
{
return false;
}
}
// 3. *and # cannot appear continuously
for(int i = 1; i < sub_word.size(); i++)
{
if(sub_word[i] == "*" && sub_word[i - 1] == "#")
{
return false;
}
if(sub_word[i] == "#" && sub_word[i - 1] == "#")
{
return false;
}
if(sub_word[i] == "#" && sub_word[i - 1] == "*")
{
return false;
}
}
return true;
}
static bool route(ExchangeType type, const std::string& routing_key, const std::string& binding_key)
{
if(type == ExchangeType::DIRECT)
{
return (routing_key == binding_key);
}
else if(type == ExchangeType::FANOUT)
{
return true;
}
//Topic Exchange: To perform pattern matching:
// 1. bind_keyand routing_keyPerform string segmentation to obtain each word array
std::vector<std::string> bkeys, rkeys;
int n_rkeys = StrHelper::split(routing_key, ".", rkeys);
int n_bkeys = StrHelper::split(binding_key, ".", bkeys);
// 2. Define the tag array and initialize [0][0]The position istrue, Other locations arefalse
std::vector<std::vector<bool>> dp(n_bkeys + 1, std::vector<bool>(n_rkeys + 1));
dp[0][0] = true;
//3. If binding_keyStart with #, then the corresponding number of #0All acts1
for(int i = 1; i < n_bkeys; i++)
{
if(bkeys[i - 1] == "#")
{
dp[i][0] = true;
continue;
}
break;
}
// 4. Use routing_keyEach word in the binding_keyEach word in matches and marks an array
for(int i = 1; i < n_bkeys + 1; i++)
{
for(int j = 1; j < n_rkeys + 1; j++)
{
if(bkeys[i - 1] == rkeys[j - 1] || bkeys[i - 1] == "*")
{
dp[i][j] = dp[i - 1][j - 1];
}
else if(bkeys[i - 1] == "#")
{
dp[i][j] = dp[i - 1][j - 1] | dp[i][j - 1] | dp[i - 1][j];
}
}
}
return dp[n_bkeys][n_rkeys];
}
};
}
#endif