Поиск в очереди

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Гость

Сообщение Гость »

Здравствуйте, господа!

Наткнулся на очень странную ситуацию.
У меня одна задача свелась к раскрашиванию графов. Есть точки, часть раскрашена в чёрный цвет. Точки, связанные с ними, также перекрашиваются. Надо выяснить, какие точки в конце концов останутся белыми.

Создал два сортированных списка (очереди) номеров точек - необработанные и обработанные. Поместил всё черные в список необработаных.
А дальше

Цикл
Беру точку - последнюю запись в списке необработанных
Удаляю из списка необработанных
Помещаю в список обработанных
В список необработанных помещаю связанные точки, которых нет в обоих списках.
Конец цикла

И вот тут наткнулся на проблему - в какой-то момент зацикливается операция Get по очереди (отслежено отладчиком) . Получается, что удаление записей из сортированной очереди может привести к нарушению сортировки... Если я беру не последнюю, а первую запись - всё нормально. Мистика!

---------------------------------------
C уважением,
Юрий Философов,
Главный программист
Корпорация "Диполь", Саратов
E-mail yufil@tacis-dipol.ru (служ)
yufil@mail.ru (дом)
ICQ#75924439
Написал: ClaList(2)
Гость

Сообщение Гость »

Хмм... Очень странно!
Именно такой обход очереди, из которой удаляются записи, и является, имхо, самым правильным. Сколько его использую - еще ни разу не сталкивался с подобными проблемами.
И разницы никакой - сортированная или нет очередь.
И потом - не очень понял твое замечание:
"может привести к нарушению сортировки"?

При чем здесь нарушение сортировки и зацикливание?
Ты же ВСЕГДА берешь последнюю запись:
Get(Queue,Records(Queue))

Какая разница, как именно в данный момент отсортирована очередь?! Ведь в любом случае будет считана последняя запись из очереди.
И еще не понял - почему и отчего зацикливание?
Разве ты не проверяешь перед/после условие While(RecordsQueue))?

Что-то мне подсказывает, что ты привел НЕ ПОЛНЫЙ алгоритм "проблемного" кода обработки очереди!?
Наверняка ведь используешь указатели и есть дополнительные условия выхода из цикла обработки? Может проблема именно в них а не в "глюках" блока RTL по обработке очередей?

=============================
С уважением, Олег А. Руденко.
Oleg_Rudenko@mail.ru
Oleg_Rudenko@mail333.com
Библиотека DynaLib
http://dynalib.narod.ru
При чем здесь нарушение сортировки и зацикливание?
Ты же ВСЕГДА берешь последнюю запись:
Get(Queue,Records(Queue))
Если бы я знал :(
Разве ты не проверяешь перед/после условие While(RecordsQueue))?
Условие проверяю, в начале цикла. Если список необработанных пуст, конец работы.
Наверняка ведь используешь указатели и есть дополнительные условия выхода из цикла обработки? Может проблема именно в них а не в "глюках" блока RTL по обработке очередей?
Указатели не использую. Грешил на переполнение стека, но увеличение размера стека ничего не дало, да и очереди весьма умеренных размеров (не больше 50000 элементов). Алгоритм полный. Конечно, есть детали по выгребанию точек (на самом деле, продуктов промышленности и с/х) и связей (несколько разнообразных классификаций) из базы. Но отладка / трассировка показывает зацикливание именно на операции Get(Queue, Key). Причём на этот момент в необработанной очереди остаётся очень немного элементов - не больше 40.

Сейчас добавил после каждого цикла пересортировку - проблема исчезла... То же самое, если выбираем не последнюю, а первую запись.

---------------------------------------
C уважением,
Юрий Философов,
Главный программист
Корпорация "Диполь", Саратов
E-mail yufil@tacis-dipol.ru (служ)
yufil@mail.ru (дом)
ICQ#75924439
Написал: ClaList(2)
Гость

Сообщение Гость »

Но отладка / трассировка показывает зацикливание именно на операции Get(Queue, Key).
Стоп, стоп! Это что - Get(Queue,Key)!?
Я ведь имел в виду ПРЯМУЮ выборку ПОСЛЕДНЕЙ записи очереди оператором Get(Queue,Records(Queue))!
А чтение записи очереди по заданному ключу предполагает, как минимум, НАЛИЧИЕ такой записи в очереди.
Более того - предполагает еще и проверку на ошибку.
Если запись по ключу не найдена, то не сработает и оператор удаления и, естественно, выхода из цикла по условию While(Records(Queue)) НИКОГДА не произойдет!

И, кстати, что значит:
"зацикливание именно на операции Get(Queue, Key)"?
Ты хочешь сказать, что вызов оператора GET приводит к "зависанию" приложения? Т.е. зацикливание производится именно ВНУТРИ RTL-оператора GET()?
Сейчас добавил после каждого цикла пересортировку - проблема исчезла... То же самое, если выбираем не последнюю, а первую запись.
Т.е., учитывая вышесказанное, получается что в некоторый момент
после удаления очередной записи сбивается КЛЮЧ, по которому производится выборка записей? Так, что-ли?
Если это так, то это довольно серьезная ошибка и следует:
- выделить пример минимально-возможного размера, на котором эта ошибка гарантированно воспроизводится
- отослать все это в SV, например через их конференции.

Кстати, или ты не указал, или я не заметил - какая версия Клариона?

=============================
С уважением, Олег А. Руденко
Более того - предполагает еще и проверку на ошибку.
Удаляется первая или последняя запись, ключ запоминаются, потом ищутся точки, связанные с удалённой. Для связанных проверяется их наличие в списках обработанных и необработанных. Вот в момент проверки и виснет.
Ты хочешь сказать, что вызов оператора GET приводит к "зависанию" приложения? Т.е. зацикливание производится именно ВНУТРИ RTL-оператора GET()?
Да. Именно так.
Т.е., учитывая вышесказанное, получается что в некоторый момент после удаления очередной записи сбивается КЛЮЧ, по которому производится выборка записей? Так, что-ли?
Похоже, так.
Если это так, то это довольно серьезная ошибка и следует: ...
Попробую. Хотя, возможно, это происходит только в определённом контексте.
Кстати, или ты не указал, или я не заметил - какая версия Клариона?
Cw6PE (лицензионная :)

---------------------------------------
C уважением,
Юрий Философов
Написал: ClaList(2)
Ответить