Некоторые наблюдения по QUEUE

Возможно кому будут интересны некоторые выводы по работе очередей, которые (выводы) сформировались в результате небольшого «копания» в них. Все выводы относятся ТОЛЬКО к реализации очередей в версии C5bee.

Динамические ключи действительно существуют и работают.

При первом поиске (Get) по неключевому полю (полям) выполняется стандартный SORT по этому полю (полям). Результат данной виртуальной сортировки сохраняется в так называемом «динамическом ключе», который представляет собой обычный массив из указателей на физические записи очереди. Под указателем имеется ввиду НЕ номер записи в очереди а именно указатель на область памяти, где физически размещена запись. Это дает возможность не перестраивать повторно уже созданные динамические ключи при изменениях очереди, таких как Add/Put/Delete/Sort.

Кроме «пользовательских» динамических ключей существует, как минимум, один системный, так называемый 0-ключ, который позволяет делать прямую выборку записи по ее номеру в текущей сортировке. Т.е. при выполнении Get(Queue,Ptr) не происходит проход по цепочке записей, а из системного ключа выбирается элемент под номером Ptr, который является указателем на физическую запись, и по этому указателю происходит прямое чтение записи в буфер.

При выполнении SORT по условию, по которому уже есть динамический ключ, сортировка не выполняется, а происходит простое переключение на новый системный ключ. Т.е. динамический ключ, соответствующий условию SORT, становится для очереди системным 0-ключем, а бывший 0-ключ становиться обычным динамическим ключем. При этом все остальные динамические ключи остаются.

Кстати, до первого SORT, системным 0-ключем является ключ по физическому порядку следования записей в очереди.
Сохраняется-ли он после SORT, узнать не удалось.

И еще один, увы, неутешительный вывод. В общем случае, не существует нормального способа встать на начало какой-либо последовательности.
Т.е. сэмулировать SET. Особенно для многокомпонентных ключей, когда не известно наименьшее значение какого-либо поля из этого ключа. Единственный ГАРАНТИРОВАННО-РАБОТАЮЩИЙ способ:

Get(Queue,Key)
if ~ErrorCode()
   Ptr# = Pointer(Queue)
else
   Add(Queue,Key)
   Get(Queue,Key)         ! На всякий случай :)
   Ptr# = Pointer(Queue)
   Delete(Queue,Key)
   if Ptr# > Records(Queue) then Ptr# = Records(Queue).
.

В принципе, учитывая высокую скорость выполнения данных операций даже на больших очередях, а так-же предположение, что SET выполняется, обычно, вне циклов, можно смириться с данной эмуляцией SET.

Но, к сожалению, даже эта конструкция не гарантирует выставление на первую запись последовательности в очереди, отсортированной только по одному полю! Поэтому, рекомендуется всегда сортировать очереди, как минимум, по двум полям. Второе поле может быть любое, желательно не STRING, и не BYTE. BYTE не рекомендуется в данном случае потому, что наименьшее значение для такого поля — 0. А 0, с большой долей вероятности, может встретиться в более чем одной записи, что сведет на нет все наши усилия по эмуляции SET.