需求:
准入授權配置文件有時候分了好幾個維度進行配置,例如 company|product|sys這種格式的配置:
1.配置 "sina|weibo|pusher" 表示 sina公司weibo產品pusher系統能夠准入,而"sina|weibo|sign"不允許准入
2.配置 "sina|*|pusher” 表示sina公司所有產品的pusher系統都能夠准入
3.配置 “*|*|pusher” 表示所有公司的所有產品的pusher系統都能夠准入
…
類似還有很多場景,好了,簡單的東西不扯蛋了.
實現:
面對這個需求我第一時間想的是如何設計模式串,如何快速實現功能,因為我現在寫的是一個C服務,所以我首先出現在我腦海的是一大堆strchr(XXX, ‘*’), strchr(XXX, ‘|’)等等東西,後面發現這個東西沒有必要自己造輪子,有現成的函數可以用,那就是fnmatch.
google了一下,發現fnmatch的資料並不是很多,大部分還都是講php函數的,所以沒辦法,只能自己寫寫測測了.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42#include <iostream>
#include <fnmatch.h>
#include <vector>
using
namespace
std;
int
main()
{
const
char
* orgin_str =
"sina|weibo|pusher"
;
char
pattern_arr[][20] = {
{
"sina|*|pusher"
},
{
"sina|*|*"
},
{
"*|weibo|*"
},
//不能被匹配的
{
"sina|pic|*"
},
{
"*|*|sign"
},
{
"*|weibo|sign"
},
{
"*|pic|sign"
},
{
"sina|pic|sign"
},
{
"*|*|*"
}
};
static
int
pattern_arr_size =
sizeof
(pattern_arr) /
sizeof
(pattern_arr[0]);
vector<
char
*> vec_str;
for
(
int
i = 0; i < pattern_arr_size; i ++)
{
vec_str.push_back(pattern_arr[i]);
}
int
ret;
int
z = 0;
while
(z < 1){
for
(
int
i = 0; i < vec_str.size(); i++)
{
ret = fnmatch(vec_str.at(i), orgin_str, FNM_PATHNAME);
if
(FNM_NOMATCH == ret){
cout<<
"sorry I'm failed ["
<< vec_str.at(i) <<
"]"
<<endl;
}
}
++z;
}
}
結果:
實驗一把,結果還不賴,完全滿足需求:
需求滿足了,我擔心的還有一個問題,那就是性能,注釋掉cout輸出,將while z語句調至1,000,000,重新編譯跑一下:
time ./fnmatch
看來效率還不錯,2.1s 進行了100W次匹配,平均2us一次,性能要求也滿足了...