And-rey: | Скачкообразный поиск в файле cidr_ru_block.txt (04.03.09 01:54) | | Первая функция выполняет построчный поиск в файле. Но это неоправданно ресурсоемко – если нужная строчка в конце файла нужно перебрать весь файл.
В общем, виде задача в том чтобы смещаться на середину файла читать строку и в зависимости от результата искать в верхней или нижней части файла.
Вторая функция частично решает эту задачу. Она выполняет 4 скачка по файлу и при любом раскладе перебирает максимум 1/4 файла.
// Поиск IP в базе (block файл)
function my_ip_runet2 ($long, $block_fale) {
$block_fp = fopen($block_fale, "rb");
while (!feof($block_fp)) {
$block_line = fgets($block_fp);
if ($long >= $cell['0'] && $long <= $cell['1']) {
$ret = $cell;
$comment .= $cell['8'] . ' => '; // иерархия
} elseif ($ret and $cell['0'] > $ret['1']) {
$ret['9'] = substr($comment, 0 , -4 ); // иерархия
break;
}
}
if ($ret) return $ret; // результат в block_fale
return false; // нет в block_fale (не Российский IP)
}
// Поиск IP в базе (block файл)
function my_ip_runet2a ($long, $block_fale) {
// поиск
function my_search ($long, $block_fp, $seek) {
while (ftell($block_fp) < $seek) {
if ($long >= $cell['0'] && $long <= $cell['1']) {
$ret = $cell;
} elseif ($ret and $cell['0'] > $ret['1']) {
break;
}
}
if ($ret) return $ret;
return false;
}
// скачки (сделать рекурсивной???)
function my_seek ($long, $block_fp, $filesize) {
$seek0 = ftell($block_fp); // начало
$seek = ftell($block_fp); // 1/2
if ($long >= $cell['0']) { // искать ниже
//$ret = my_search($long, $block_fp, $filesize); //***
fseek($block_fp, floor($seek + ($filesize / 4 )), SEEK_SET );
$seek2 = ftell($block_fp); // 3/4
if ($long >= $cell['0']) { // от 3/4 до конца
$ret = my_search($long, $block_fp, $filesize);
} else { // от 1/2 до 3/4
fseek($block_fp, $seek, SEEK_SET ); // к 1/2
$ret = my_search($long, $block_fp, $seek2);
}
} else { // искать выше
//fseek($block_fp, $seek0, SEEK_SET); //***
//$ret = my_search($long, $block_fp, $seek); //***
$seek2 = ftell($block_fp); // 1/4
if ($long >= $cell['0']) { // от 1/4 до 1/2
$ret = my_search($long, $block_fp, $seek);
} else { // от начала до 1/4
fseek($block_fp, $seek0, SEEK_SET ); // к началу
$ret = my_search($long, $block_fp, $seek2);
}
}
if ($ret) return $ret;
return false;
}
// вход
$block_fp = fopen($block_fale, "rb");
$ret = my_seek($long, $block_fp, $filesize);
// выход
if ($ret) return $ret; // результат в block_fale
return false; // нет в block_fale (не Российский IP)
}
Данную функцию надо бы сделать рекурсивной, чтоб можно было задавать количество скачков.
P.S Функции полностью подходят для использования в скрипте из первого поста.
P.P.S Похоже, что это уже больше интерес именно к поиску в файлах . |
|