Руководство администратора баз данных Informix. - [10]
2.2.5.2 Итераторы
Итератор - это программный объект, который осуществляет итеративную (циклическую) обработку некоторого множества данных. Итераторы различаются типом производимой обработки, но имеют единообразный внешний интерфейс. Каждый итератор открывает один (или более) входных потоков данных (data flow), последовательно считывает их и, после обработки, помещает результаты в выходной поток. Итератору безразличен источник входного потока и назначение выходного потока - это может быть диск, другой итератор, сетевое соединение. Мы будем говорить о поставщиках и потребителях потоков данных. Ниже перечислены типы итераторов, применяемые в INFORMIX-OnLine DS:
SCAN - Сканирует фрагментированные и нефрагментированные таблицы и индексы. NESTED LOOP JOIN - Реализует стандартную логику соединений методом вложенных циклов (читает строку из одной таблицы, находит все совпадения во второй таблице, читает следующую строку из первой таблицы и т. д.). MERGE JOIN - Выполняет фазу слияния для соединения методом сортировки и слияния. HASH JOIN - Реализует новый метод соединений с хешированием. Для одной из двух соединяемых таблиц строится хеш-таблица, вторая таблица зондируется. Оптимизатор решает, какая из таблиц будет хешироваться. GROUP - Группирует данные (GROUP BY) и вычисляет агрегатные функции. SORT - Сортирует данные. MERGE - Выполняет объединения UNION и UNION ALL (для UNION используется комбинация итераторов MERGE и SORT). REMOTE - Реализует удаленные сканирования для операторов SELECT.
Итератор как программный объект состоит из статических и динамических структур данных. Статическая структура содержит ссылки на функции (или методы), применимые к итератору. Динамическая структура содержит информацию о текущем состоянии итератора (открыт, закрыт, выполняет очередную итерацию), одну или две ссылки на поставщиков.
Методы итератора
CREATE() - Создает итератор. Выделяет память для итератора, инициализирует его структуры, а также остальные методы (open(), next(), close(), free()), т.е. устанавливает ссылки на функции, соответствующие данному типу итератора. Затем вызывает метод create() для своих итераторов-поставщиков, которые создадут своих поставщиков, если таковые имеются, и т. д. Таким образом, вызов метода create() для корневого итератора приводит к созданию всего дерева итераторов.
OPEN() - Запускает итератор. Выполняются специфические для данного типа итератора инициализирующие действия, возможно, запрос дополнительной памяти. Например, при запуске итератора сканирования определяется, какие фрагменты необходимо сканировать, устанавливается указатель на первый из них, создается временная таблица (если она нужна), посылается сообщение
MGM (MGM - компонента сервера, которая регулирует выделение ресурсов под запросы, обрабатываемые средствами PDQ; см. об этом ниже, п. "Баланс между OLTP и DSS-приложениями") о запуске потока сканирования. Далее применяется метод open() по отношению к поставщикам итератора, которые применят его к своим поставщикам и т.д. Таким образом, для запуска всего дерева итераторов достаточно применить метод open() к корневому итератору.
NEXT() - Выполняет одну итерацию. Выполнение начинается с того, что итератор применяет метод next() к своим поставщикам, заставляя их также применить next() к своим поставщикам и т. д., пока не сработают итерации поставщиков нижнего уровня. Затем данные поднимаются снизу вверх - каждый итератор, получив данные от своего поставщика, применяет к ним свой специфический вид обработки и передает результат своему потребителю. Метод next() применяется циклически, пока не поступит признак конца потока данных.
CLOSE() - Закрывает итератор. Высвобождает память, выделенную при запуске. Фактически, эта память могла уже быть высвобождена методом next(), когда он получил признак конца данных, поскольку общий принцип состоит в том, чтобы освобождать память сразу же, как только она становится не нужна. Однако, это не всегда возможно. Поэтому на метод close() возлагается ответственность за то, чтобы память в любом случае была освобождена.
Метод close() рекурсивно применяется к поставщикам, тем самым, закрывается все дерево итераторов.
FREE() - Освобождает итератор. Высвобождает память, выделенную при создании. Применяет free() к поставщикам, таким образом, освобождается все дерево итераторов.
Благодаря единообразию интерфейса, итераторы разных типов могут соединяться друг с другом произвольным образом (рис. 5). Итератор не заботится о том, какой тип имеют его поставщики, поскольку он взаимодействует с ними только посредством методов. Из описания методов следует, что запуск дерева, составленного из итераторов, реализует их параллельное выполнение. Для каждого итератора создается поток выполнения, который продвигается по мере того, как получает данные от своих поставщиков. Таким образом в сервере реализуется вертикальный параллелизм - одновременное, конвейерное выполнение различных итераторов.
Другой вид параллелизма - горизонтальный - заключается в том, что вместо одного итератора (например, сканирования) создается несколько однотипных параллельно выполняемых итераторов. Горизонтальный параллелизм реализуется при помощи итераторов специального вида - итераторов обмена (EXCHANGE). После того, как дерево реализации запроса построено, оптимизатор определяет, какие его компоненты имеет смысл распараллелить. Над такой компонентой вставляется итератор EXCHANGE. Итератор EXCHANGE создает и запускает несколько экземпляров своего поставщика, обеспечивает координацию поступающих от них потоков данных и их передачу своему потребителю. Передача данных осуществляется в этом случае не через входы потребителя, а через очереди пакетов в разделяемой памяти.
Жизнь современного человека плотно связана с видеоиграми. Даже если вы не играете сами, в вашем окружении наверняка найдутся заядлые геймеры, а новости из индустрии игр зачастую не обходят и вас стороной. Это положение дел приводит к вопросам: а что же такое видеоигры и какое место они занимают в жизни человека? Поиском ответов на них занимается дисциплина game studies. Александр Ветушинский – один из ведущих российских представителей этого направления исследований. Его книга «Игродром» – философское осмысление этапов развития игровой индустрии, анализ.
В процессе чтения вы познакомитесь с основами программирования и, в частности, языка JavaScript, а также выполните несколько небольших проектов. Один из самых интересных проектов — создание своего языка программирования.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Это практическое руководство разработчика программного обеспечения на Visual Basic .NET и ADO.NET, предназначенное для создания приложений баз данных на основе WinForms, Web-форм и Web-служб. В книге описываются практические способы решения задач доступа к данным, с которыми сталкиваются разработчики на Visual Basic .NET в своей повседневной деятельности. Книга начинается с основных сведений о создании баз данных, использовании языка структурированных запросов SQL и системы управления базами данных Microsoft SQL Server 2000.