7.5. ПРИМЕР ПАКЕТА РАБОТЫ С ТАБЛИЦАМИ

Следующий пример иллюстрирует использование пакетов для организации простого взаимодействия пользователя с довольно сложными процедурами.

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

С точки зрения пользователя, пакет чрезвычайно прост. Существует тип с именем ITEM — тип элемента таблицы, есть процедура INSERT для включения элементов в таблицу и процедура RETRIEVE для извлечения элемента с наименьшим порядковым номером. Если таблица пуста, то возвращается специальный элемент NULL-ITEM, а если таблица заполнена, то при выяпяй nnniiftnvnki INRFRT по.чЛужляйтся искпючание TABLE _FULL-

Ниже приведена схема такого пакета. Пользователю известна только спецификация пакета.

package TABLE_MANAGER is   type ITEM is      record         ORDER_NUM   : INTEGER;         ITEM_CODE   : INTEGER;         QUANTITY    : INTEGER;         ITEM-TYPE   : CHARACTER;      end record;   NULL-ITEM : constant ITEM :=      (ORDER_NUM | ITEM_CODE | QUANTITY => 0, ITEM_TYPE => ' ');  procedure INSERT (NEWJTEM : in ITEM);  procedure RETRIEVE (FIRSTJTEM : out ITEM);  TABLE_FULL : exception; -— это исключение возбуждается в процедуре end;                      -— INSERT, если таблица заполнена

Детали реализации таких пакетов могут быть достаточно сложными; в данном случае используются двусвязные списки внутренних элементов. Локальная вспомогательная процедура EXCHANGE используется для перемещения внутренних элементов из списка занятых в список свободных. Начальные связи таблицы устанавливаются в разделе инициализации. Нет необходимости показывать пользователям тело пакета.

package body TABLE_MANAGER is    SIZE : constant := 2000;   subtype INDEX is INTEGER range 0 .. SIZE;   type INTERNAL-ITEM is      record         CONTENT : ITEM;         SUCC    : INDEX;         PRED     : INDEX;      end record;   TABLE : array (INDEX) of INTERNAL-ITEM;   FIRST_BUSY_ITEM : INDEX := 0;   FIRST_FREE_ITEM : INDEX := 1;   function FREE_LIST_EMPTY return BOOLEAN is ... end;   function BUSY_LIST_EMPTY return BOOLEAN is ... end;   procedure EXCHANGE (FROM : in INDEX; TO : in INDEX) is ... end;   procedure INSERT (NEWJTEM : in ITEM) is   begin      if FREE_LIST_EMPTY then         raise TABLE_FULL;      end if;      -— остальная часть кода подпрограммы INSERT    end INSERT;   procedure RETRIEVE (FIRSTJTEM : out ITEM) is ... end;begin   -— инициализация связей таблицыend TABLE_MANAGER;