Message-Queues beta 1.1
A Message-Queues based Cpp
 
载入中...
搜索中...
未找到
route.hpp
浏览该文件的文档.
1
9#pragma once
10#include <iostream>
11#include "../common/msg.pb.h"
12#include "../common/logger.hpp"
13#include "../common/helper.hpp"
14namespace XuMQ
15{
17 class Router
18 {
19 public:
24 static bool isLegalRoutingKey(const std::string &routing_key)
25 {
26 // 判断是否有非法字符
27 for (auto &ch : routing_key)
28 {
29 if ((ch >= 'a' && ch <= 'z') ||
30 (ch >= 'A' && ch <= 'Z') ||
31 (ch >= '0' && ch <= '9') ||
32 (ch == '_' || ch == '.'))
33 continue;
34 else
35 {
36 error(logger, "routing key不合法! 因为含有非法字符 %c ", ch);
37 return false;
38 }
39 }
40 return true;
41 }
52 static bool isLegalBindingKey(const std::string &binding_key)
53 {
54 for (auto &ch : binding_key)
55 {
56 if ((ch >= 'a' && ch <= 'z') ||
57 (ch >= 'A' && ch <= 'Z') ||
58 (ch >= '0' && ch <= '9') ||
59 (ch == '_' || ch == '.') ||
60 (ch == '#' || ch == '*'))
61 continue;
62 else
63 {
64 error(logger, "binding key不合法! 因为含有非法字符 %c ", ch);
65 return false;
66 }
67 }
68 std::vector<std::string> sub_words;
69 StrHelper::split(binding_key, ".", sub_words);
70 for (auto &word : sub_words)
71 {
72 if (word.size() > 1 &&
73 (word.find("*") != std::string::npos ||
74 word.find("#") != std::string::npos))
75 {
76 error(logger, "binding key不合法! 因为字符和通配符连续出现 %s ", word.c_str());
77 return false;
78 }
79 }
80 for (int i = 1; i < sub_words.size(); i++)
81 {
82 if (sub_words[i] == "#" && sub_words[i - 1] == "*")
83 {
84 error(logger, "binding key不合法! 因为通配符连续出现");
85 return false;
86 }
87 if (sub_words[i] == "#" && sub_words[i - 1] == "#")
88 {
89 error(logger, "binding key不合法! 因为通配符连续出现");
90 return false;
91 }
92 if (sub_words[i] == "*" && sub_words[i - 1] == "#")
93 {
94 error(logger, "binding key不合法! 因为通配符连续出现");
95 return false;
96 }
97 }
98 return true;
99 }
105 static bool route(ExchangeType type, const std::string &routing_key, const std::string &binding_key)
106 {
107 if (type == ExchangeType::DIRECT)
108 return routing_key == binding_key;
109 if (type == ExchangeType::FANOUT)
110 return true;
111
112 // 动态规划进行匹配
113 // 二维数组标记每次匹配的结果 通过最终数组末尾的位置来判定整体是否匹配成功
114 // 初始化 dp[0][0] = 1;
115 // 遇到 普通字符
116 // 如果匹配成功 dp[i][j] = dp[i-1][j-1];
117 // 如果匹配失败 dp[i][j] = 0;
118 // 遇到 通配符 `#`
119 // 初始化 bindingkey以 `#`起始时 对应行第一个字符初始化为1
120 // dp[i][j] = dp[i][j-1] || dp[i-1][j] || dp[i-1][j-1];
121 // 遇到 通配符 `*` 始终认为单词匹配成功
122 // dp[i][j] = dp[i-1][j-1];
123 std::vector<std::string> bkeys, rkeys;
124 // 字符串风格 得到单词数组
125 int n_bkey = StrHelper::split(binding_key, ".", bkeys);
126 int n_rkey = StrHelper::split(routing_key, ".", rkeys);
127 std::vector<std::vector<bool>> dp(n_bkey + 1, std::vector<bool>(n_rkey + 1, false));
128 // 初始化
129 dp[0][0] = true;
130 // bindingkey以#起始的行第0列置为1
131 for (int i = 1; i <= bkeys.size(); i++)
132 {
133 if (bkeys[i - 1] == "#")
134 {
135 dp[i][0] = true;
136 continue;
137 }
138 break;
139 }
140 // 匹配
141 for (int i = 1; i <= n_bkey; i++)
142 {
143 for (int j = 1; j <= n_rkey; j++)
144 {
145 if (bkeys[i - 1] == rkeys[j - 1] || bkeys[i - 1] == "*")
146 {
147 dp[i][j] = dp[i - 1][j - 1];
148 }
149 else if (bkeys[i - 1] == "#")
150 {
151 dp[i][j] = dp[i - 1][j - 1] | dp[i - 1][j] | dp[i][j - 1];
152 }
153 }
154 }
155 return dp[n_bkey][n_rkey];
156 }
157 };
158}
路由管理器
Definition route.hpp:18
static bool isLegalRoutingKey(const std::string &routing_key)
判断路由关键字是否合法
Definition route.hpp:24
static bool isLegalBindingKey(const std::string &binding_key)
判断绑定关键字是否合法
Definition route.hpp:52
static bool route(ExchangeType type, const std::string &routing_key, const std::string &binding_key)
路由选择
Definition route.hpp:105
static size_t split(const std::string &str, const std::string &sep, std::vector< std::string > &result)
将字符串分割为多个子字符串
Definition helper.hpp:152
Definition channel.hpp:22
Xulog::Logger::ptr logger
日志器的智能指针类型
Definition logger.hpp:24
ExchangeType
Definition msg.pb.h:66
@ DIRECT
Definition msg.pb.h:68
@ FANOUT
Definition msg.pb.h:69