SASGIS - SAS.Планета
View Issue Details
0001539SAS.ПланетаРефакторингpublic03-09-2012 14:3602-10-2012 12:29
Dima2000 
Dima2000 
normalminorN/A
resolvedfixed 
WindowsXPProfessional SP3
120808 
121010121010 
0001539: Улучшение офлайн поиска по файлам *.mp
1. Сейчас ищется лишь по совпадению в начале строки (т.е. маска "текст*"), предлагаю модифицировать u_GeoCoderByPolishMap.pas чтобы искалось по маске "*текст*", т.е. совпадение в любом месте строки.
Для этого строки 551-554
  VSearch := 'LABEL='+VSearch;
  while (PosEx(VSearch, VStr, i)>i) {and (i>0) }do begin
    VLinkErr := false;
    i := PosEx(VSearch, VStr, i);
заменить на
  while true do begin
    VLinkErr := false;
    i := PosEx(VSearch, VStr, i) + 1;
    if i = 1 then break; // больше не нашли?
    j := i - 1;
    while (Vstr[j] <> #$A) and (j > 0) do dec(j); // начало строки с найденными данными
    if copy(Vstr, j + 1, 6) <> 'LABEL=' then continue; // найденные данные не в теге Label?
Таким образом, текст будет искаться везде, потом проверяться в теге Label ли он, и если нет - продолжать поиск дальше.

Заодно вместо двух одинаковых вызовов PosEx будет лишь один, всяко экономия тактов на многомегабайтых файлах.
2. В том же файле после строки 557
while (copy(Vstr,l,1)<>'[') and (l>0) do dec(l); // начало блока с найденными данными
добавить команду
vStr2 := copy(VStr, l, k - l); // вырежем весь блок с найденными данными
и дальше пользоваться только этой переменной, а не всем многомегабайтным VStr. Если в файле отсутствуют какие-то теги, то просматривать его каждый раз до конца глупо, достаточно просматривать до конца блока. Имхо создание строковой переменной в сотню байтов быстрее пятикратного просмотра сотни мегабайт ОЗУ...
No tags attached.
related to 0001320closed Garl Хочется иметь полностью офлайновый поиск 
? u_GeoCoderByPolishMap.pas (26,012) 04-09-2012 06:37
http://bugtracker.sasgis.org/file_download.php?file_id=998&type=bug
Issue History
03-09-2012 14:36Dima2000New Issue
03-09-2012 14:50vdemidovNote Added: 0008667
03-09-2012 14:50vdemidovStatusnew => feedback
03-09-2012 14:50vdemidovAssigned To => Dima2000
03-09-2012 14:50vdemidovProduct Version => 120808
03-09-2012 14:50vdemidovTarget Version => 121010
03-09-2012 15:47Dima2000Note Added: 0008669
03-09-2012 15:47Dima2000Statusfeedback => assigned
03-09-2012 15:47Dima2000File Added: u_GeoCoderByPolishMap.pas
03-09-2012 15:57vdemidovNote Added: 0008670
03-09-2012 16:18Dima2000Relationship addedrelated to 0001320
03-09-2012 17:37GarlNote Added: 0008671
03-09-2012 17:37GarlNote Edited: 0008671bug_revision_view_page.php?bugnote_id=8671#r4194
03-09-2012 19:14GarlNote Added: 0008672
04-09-2012 05:44Dima2000File Deleted: u_GeoCoderByPolishMap.pas
04-09-2012 06:37Dima2000Note Added: 0008673
04-09-2012 06:37Dima2000File Added: u_GeoCoderByPolishMap.pas
04-09-2012 07:11GarlNote Added: 0008674
04-09-2012 07:17Dima2000Note Added: 0008676
04-09-2012 07:24GarlNote Added: 0008677
13-09-2012 13:20Dima2000Note Added: 0008873
13-09-2012 13:21GarlStatusassigned => resolved
13-09-2012 13:21GarlResolutionopen => fixed
02-10-2012 12:29vdemidovFixed in Version => 121010

Notes
(0008667)
vdemidov   
03-09-2012 14:50   
Ждем PullRequest-а
(0008669)
Dima2000   
03-09-2012 15:47   
У меня репо нету, сами подправьте плиз. Я могу лишь подправить файлик и приложить его сюда. Приложил.

Для сравнения, реализация п.2 при поиске слова "красная" на файле 157М уменьшает время поиска с 25с до 3с (это без учёта времени чтения файла, которое тоже 3с).
(0008670)
vdemidov   
03-09-2012 15:57   
Репо скачивается 20 секунд. Сами сделаете пул реквест.
(0008671)
Garl   
03-09-2012 17:37   
ок сейчас потестим и пульнём :)

(0008672)
Garl   
03-09-2012 19:14   
сделал, а затем увидел прикреплённый файл.
чуток оттуда займу оптимизаций, но уже на завтра.
(0008673)
Dima2000   
04-09-2012 06:37   
Garl, замечания по коммиту 433ff3ee8f27.
1. Строку 561 убрать! Из-за неё если текст найдётся не в теге Label, а в любом другом до него, то остаток до конца блока проверяться уже не будет! И соответственно может пропустить вхождение. В моём коде её и не было.
2. Зачем в строке 565 повторно вычисляется k? Оно же уже есть из строки 559 и гарантированно не меньше длины VStr2. А что дальше кучка лишних if i<k - наплевать, они всегда истинны, а времени тратят не много.
3. Зачем в строке 563 вырезается и конечный [END], он же всё равно далее нигде не нужен?
4. Зачем введена новая Vi, если и с i всё работало хорошо? Впрочем, как хотите.
5. Зачем используется VTempList если города можно сразу в VCityList запихивать? Не улавливаю преимущества лишней обёртки над TStringList. Но оставлю как есть.
6. Отступ назад до начала блока работает неправильно если в теге Label (или любом другом до него) встретится символ '['. Надо проверять что тег сидит в начале строки.
7. В строке 588 strtoint вылетит если код города неправильный или POI/POLYLINE принадлежит нескольким городам (а такое стандартом разрешено).
8. В строке 589 вылетит и индексация массива если код города неправильный (меньше 1).
9. Искать $D$A в строке 532 по всему файлу глупо, достаточно найти первый же $A и проверить предыдущий символ. Только пропустить самое начало файла, чтобы не уйти в минус.
10. Предлагаю если не найден тег [CITIES] в строке 534 не запускать весь цикл по списку городов. Сейчас куча лишних просмотров всего VStr.
11. Ну а если запускать, то после нахождения [END сразу отрезать блок в VStr2 и города извлекать уже из неё.
12. Поиск строки 'label=' и любого её подмножества найдёт СЛИШКОМ много лишнего.
13. В строках 557 и 562 индекс надо проверять до проверки массива. В реале это несущественно, за начало файла цикл и так не выйдет, но всё же.
14. Почему в строке 542 ищется конец строки с последующим тегом REGIONIDX?! А если дальше будет другой тег?!

Короче, всё это поправил и приложил обновлённый юнит.
Дальше оптимизировать смысла мало, скорости это уже не добавит.

Оставшиеся баги.
б1. Надо вообще все теги проверять что они в начале строки. А то мало ли что напишут в описаниях, вдруг в них встретится слово равное тегу?
б2. Неправильно обрабатываются списки городов, если точка/линия принадлежит нескольким городам. В вывод город не попадёт вообще.
б3. Вот бы по аналогии с городами обрабатывать индексы регионов и стран.
(0008674)
Garl   
04-09-2012 07:11   
строка 531
  if VStream.Size < 10 then exit; // файл слишком маленький
не катит ибо в строке 526 у нас VStream.Free;
(0008676)
Dima2000   
04-09-2012 07:17   
Упс, извиняюсь. Тогда так:
if length(VStr) < 10
(0008677)
Garl   
04-09-2012 07:24   
щас ещё погоняю ибо есть претензии к данным которые выводятся.
(0008873)
Dima2000   
13-09-2012 13:20   
По моему данный тикет можно закрывать как решенный?