В свое время в язык были добавлены операторы:
GETSTATE
RESTORESTATE
FREESTATE
Кто-нибудь их использует в своем коде?
Какие впечатления?
Есть ли подводные камни?
Как они ведут себя в С6?
Помнится, я экспериментировал с ними и обнаружил, что в рекурсивных процедурах теряются позиции. Сейчас иногда использую в процедурах, которые могут попасть в фильтр для View. Например, для случая, когда нужно отфильтровать при наличии заданного значения в неключевом поле дочернего файла.
С уважением,
Владимир Смелик vovs@bigfoot.com
(Добавление)
Конкретно эти функции не использую - юзаю свои функции, которые написаны по их потобию.
Просто мои были написаны еще на C50, когда вышеназванных функций в языке не было. И привык с тех пор.
Так что мой выбор никак не связан с надежностью стандартных функций.
Написаны они вполне корректно, код простой и в нем просто не откуда взятся "подводным камням".
Алгоритм C60 практически аналогичен C55.
Рекурсия никак не должна влиять на код этих функций.Помнится, я экспериментировал с ними и обнаружил, что в рекурсивных процедурах теряются позиции. Сейчас иногда использую в процедурах, которые могут попасть в фильтр для View. Например, для случая, когда нужно отфильтровать при наличии заданного значения в неключевом поле дочернего файла.
Как могли терятся позиции? Есть только одно предположени - возможно неправильное использование этих функций вследствие неочевидности некоторых внутренних вещей драйвера и их неосвещение в документации. Речь идет о VIEW и о том, что используемый ключ любого из файлов этого VIEW неопределен ДО первого NEXT/PREVIOUS. Если, конечно, не использовалось явное задание файлового ключа.
Т.е.:
Код: Выделить всё
MyView VIEW(MyFile).
...
Open(MyView) ! MyFile{PROP:CurrentKey} &= NULL
Set(MyView) ! MyFile{PROP:CurrentKey} &= NULL
Loop
Next(MyView) ! только сейчас может быть определен текущий ключ
...
.
Код: Выделить всё
...
Set(MYF:Key1) ! Уже определен текущий ключ
Open(MyView)
Loop
Next(MyView)
...
.
Для большей свободы и гибкости и для предотвращения вероятных коллизий с ключами, я предпочитаю обьявлять алиасы для наиболее "нагруженных" файлов.Например, для случая, когда нужно отфильтровать при наличии заданного значения в неключевом поле дочернего файла.
Например, каталог анкет клиентов (дерево структуры), таблицы документов и их позиций.
Кроме всего прочего такой подход позволяет несколько уменьшить время обработки в циклах (рекурсиях) за счет отказа от сохранения/восстановления текущей позиции обхода записей.
В основном я использую свои аналоги этих процедур только для сохранения/восстановления буфера записи, MEMO-полей и некоторых флажков состояния записи.
=============================
С уважением, Олег А. Руденко.
Oleg_Rudenko@mail.ru
Oleg_Rudenko@mail333.com
Библиотека DynaLib
http://dynalib.narod.ru
(Добавление)
В С55 при вложенных вызовах по одному и тому же файлу (это это не совсем и рекурсия) слетает как позиция в файле, так и буфер.
Т.е. код вида:
SaveState1 LONG
SaveState2 LONG
...
SaveState1 = GETSTATE(MyTable)
....
SaveState2 = GETSTATE(MyTable)
...
RESTORESTATE(MyTable,SaveState2)
FREE(MyTable,SaveState2)
...
RESTORESTATE(MyTable,SaveState1)
FREE(MyTable,SaveState1)
гарантировано приведет к опустошению буфера записи и сбросу указателя после второго восстановления состояния.
Так что эти функции очень капканистые, приключения ловятся на ровном месте...
--
Best regards,
Vadim mailto:vadim@softcreator.com
ICQ: 82308757
Вероятно, я именно с этим и столкнулся, но в рекурсивной процедуре. Т.е. получается, что в одной нитке я могу хранить не более одного *STATE на один файл. Так?
С уважением,
В.Смелик
Типа того. Не "вкладывать" сохранение одного и того же файла во внурть второго по нему же. Последовательно вызывать - проблем на последних релизах C55 у меня не было.
--
Best regards,
Vadim
А влияние на скорость? Подозреваю, должно быть минимально.
Но все же...
Наконец решил посмотреть объем баз, с которыми сейчас развлекаюсь.
В самой большой таблице - больше 10 млн записей... Каждый чих может влиять на общее время обработки.
С уважением,
В.Смелик
Написал: ClaList(2)