Я пишу прокси-сервер. Он применяет различные правила к сайтам, которые соответствуют спискам. Например, мы можем блокировать List A и использовать другой прокси-сервер для извлечения содержимого в список Б.Лучший способ сопоставления (поиска) URL-адреса в списке на C (реализация белого списка или черного списка)?
Например, список А:
.google.com
blogger.com
sourceforge.net
ytimg.com
http://media-cache-*.pinterest.com/*
images-amazon.com
*.amazonaws.com
twitter.com
fbcdn.net
google-analytics.com
staticflickr.com
Список Б:
ytimg.com
youtube.com
В настоящее время матч функция:
struct proxy_t *
match_list(char *url) {
// 2KB line should be enough
char buf[2048];
int pos = 0, size;
struct acllist *al = config->acl_h;
struct acl *node = al->data;
while (node != NULL) { // iterate list
pos = 0; // position in list file
size = strlen(node->data); // node->data holds a URL list
while (1) { // iterate each line in list
readline(buf, node->data, &pos, size);
if (buf[0] == 0) break;
if (strcasestr(url, buf) != NULL
|| !fnmatch(buf, url, FNM_CASEFOLD)) {
return node->proxy;
}
}
node = node->next;
}
printf("Not Matched\n");
return config->default_proxy;
}
То есть, перебирать два списка файлов, построчно читать, использовать strcasestr и fnmatch в соответствии с одним URL.
Он отлично работает. Но если списки становятся больше и больше, скажем, 10 000 строк в списке и 5 списках, я полагаю, что это не будет эффективным решением, так как это алгоритм O (N).
Я подумываю о добавлении счетчика попаданий в каждую строку матча. При заказе строк соответствия это может уменьшить среднюю длину поиска. Например:
.google.com|150
blogger.com|76
sourceforge.net|43
ytimg.com|22
Есть ли другие идеи?
Речь идет не о разборе URL. Речь идет о том, как эффективно сопоставлять список URL-адресов. – strongwillow
Возможно, вы захотите посмотреть в хэш-таблицы для хранения URL-адресов или какого-либо дерева поиска. –
Спасибо, всем. Наконец я разобрался. Независимо от использования хеш-таблицы или дерева поиска, сделайте это со своим доменом (xxx.xx).Как только мы найдем узел (также заголовок связанного списка), перечислим список и сопоставим его с ** fnmatch ** и ** strstr **. – strongwillow