Блог And-rey.ru Блог And-rey.ru Блог And-rey.ru
Логин:
Регистрация Пароль:

Начало / ip_runet / Скачкообразный поиск в файле cidr_ru_block.txt


And-rey:Скачкообразный поиск в файле cidr_ru_block.txt (04.03.09 01:54)
  
Первая функция выполняет построчный поиск в файле. Но это неоправданно ресурсоемко – если нужная строчка в конце файла нужно перебрать весь файл.
 
В общем, виде задача в том чтобы смещаться на середину файла читать строку и в зависимости от результата искать в верхней или нижней части файла.
Вторая функция частично решает эту задачу. Она выполняет 4 скачка по файлу и при любом раскладе перебирает максимум 1/4 файла.
 
PHP
  1. // Поиск IP в базе (block файл)
  2. function my_ip_runet2 ($long, $block_fale) {
  3.     $block_fp = fopen($block_fale, "rb");
  4.     while (!feof($block_fp)) {
  5.         $block_line = fgets($block_fp);
  6.         $cell = preg_split('/\t/', trim($block_line));
  7.         if ($long >= $cell['0'] && $long <= $cell['1']) {
  8.             $ret = $cell;
  9.             $comment .= $cell['8'] . ' => ';     // иерархия
  10.         } elseif ($ret and $cell['0'] > $ret['1']) {
  11.             $ret['9'] = substr($comment, 0, -4); // иерархия
  12.             break;
  13.         }
  14.     }
  15.     fclose($block_fp);
  16.     if ($ret) return $ret; // результат в block_fale
  17.     return false;          // нет в block_fale (не Российский IP)
  18. }
  19.  
  20.  
  21. // Поиск IP в базе (block файл)
  22. function my_ip_runet2a ($long, $block_fale) {
  23.    
  24.     // поиск
  25.     function my_search ($long, $block_fp, $seek) {
  26.         while (ftell($block_fp) < $seek) {
  27.             $cell = preg_split('/\t/', trim(fgets($block_fp)));
  28.             if ($long >= $cell['0'] && $long <= $cell['1']) {
  29.                 $ret = $cell;
  30.             } elseif ($ret and $cell['0'] > $ret['1']) {
  31.                 break;
  32.             }
  33.         }
  34.         if ($ret) return $ret;
  35.         return false;
  36.     }
  37.    
  38.    
  39.     // скачки (сделать рекурсивной???)
  40.     function my_seek ($long, $block_fp, $filesize) {
  41.        
  42.         $seek0 = ftell($block_fp);                          // начало
  43.         fseek($block_fp, floor($filesize / 2), SEEK_SET);
  44.         fgets($block_fp);
  45.         $seek = ftell($block_fp);                           // 1/2
  46.         $cell = preg_split('/\t/', trim(fgets($block_fp)));
  47.        
  48.         if ($long >= $cell['0']) {                          // искать ниже
  49.            
  50.             //$ret = my_search($long, $block_fp, $filesize); //***
  51.            
  52.             fseek($block_fp, floor($seek + ($filesize / 4)), SEEK_SET);
  53.             fgets($block_fp);
  54.             $seek2 = ftell($block_fp);                      // 3/4
  55.             $cell = preg_split('/\t/', trim(fgets($block_fp)));
  56.            
  57.             if ($long >= $cell['0']) {                      // от 3/4 до конца
  58.                 $ret = my_search($long, $block_fp, $filesize);
  59.             } else {                                        // от 1/2 до 3/4
  60.                 fseek($block_fp, $seek, SEEK_SET);          // к 1/2
  61.                 $ret = my_search($long, $block_fp, $seek2);
  62.             }
  63.            
  64.         } else {                                            // искать выше
  65.            
  66.             //fseek($block_fp, $seek0, SEEK_SET);            //***
  67.             //$ret = my_search($long, $block_fp, $seek);     //***
  68.            
  69.             fseek($block_fp, floor($seek / 2), SEEK_SET);
  70.             fgets($block_fp);
  71.             $seek2 = ftell($block_fp);                      // 1/4
  72.             $cell = preg_split('/\t/', trim(fgets($block_fp)));
  73.            
  74.             if ($long >= $cell['0']) {                      // от 1/4 до 1/2
  75.                 $ret = my_search($long, $block_fp, $seek);
  76.             } else {                                        // от начала до 1/4
  77.                 fseek($block_fp, $seek0, SEEK_SET);         // к началу
  78.                 $ret = my_search($long, $block_fp, $seek2);
  79.             }
  80.    
  81.         }
  82.        
  83.         if ($ret) return $ret;
  84.         return false;
  85.     }
  86.    
  87.    
  88.     // вход
  89.     $filesize = filesize($block_fale);
  90.     $block_fp = fopen($block_fale, "rb");
  91.    
  92.     $ret = my_seek($long, $block_fp, $filesize);
  93.    
  94.     // выход
  95.     fclose($block_fp);
  96.     if ($ret) return $ret; // результат в block_fale
  97.     return false;          // нет в block_fale (не Российский IP)
  98.    
  99. }

Данную функцию надо бы сделать рекурсивной, чтоб можно было задавать количество скачков.
 
P.S Функции полностью подходят для использования в скрипте из первого поста.
P.P.S Похоже, что это уже больше интерес именно к поиску в файлах Well.
 




    <Ответить>
    Имя:
    Тема:*
    Сообщение:[b] [i] [u] [s] [sub] [sup] [left] [center] [right] [justify] [img] [url] [youtube]   [help]
    *
     

     

    Я сделаю свой блог — с блэкджеком и шлюхами!

    2006-2012, CC-BY: Andrey A.