- •Программирование
- •1. Архитектура машинной памяти
- •2. Внешние запоминающие устройства.
- •3. Адресация памяти.
- •4. Три уровня представления данных в автоматизированных информационных системах.
- •5. Внутренняя структура записи
- •6. Типы структур данных
- •9. Способы хранения, основанные на преобразовании кода записи в ее адрес
- •10. Массивы
- •11. Стеки
- •12. Очередь
- •13. Таблица
- •14. Основные понятия и принципы сортировки
- •15. Основные методы сортировки линейных структур данных
- •16. Внешняя сортировка
- •17. Основные принципы информационного поиска
- •18. Последовательный поиск
- •20. Двоичный поиск
- •21. Блочный поиск
9. Способы хранения, основанные на преобразовании кода записи в ее адрес
В
операционных системах и в системах
управления базами данных широко
используются способы размещения,
основанные на преобразовании кода
записи в ее адрес, которые обеспечивают
прямой доступ к данным. Адрес хранения
записи в этом случае определяется не
логическими действиями над массивом
записей, т.е. не по расположению
относительно ранее найденных или
записанных данных, ас помощью некоторой
процедуры над кодом записи или ее ключом.
При этом время обращения к памяти не
зависит ни от расположения данных, к
которым осуществлялось предыдущее
обращение, ни от местоположения данных,
к которым осуществляется текущее
обращение.
Функции, осуществляющие процедуру над ключом и генерирующие адрес записи, называются функциями преобразования. В литературе по обработке данных эти функции называют часто рандомизирующими (от англ. random access — произвольный доступ). Основное требование, предъявляемое к функции преобразования, состоит в том, что она должна генерировать уникальный адрес.
Для вычисления адресов можно использовать следующее преобразование: ai = Ki - Р, здесь аi - номер или адрес записи, Ki — значение ключа записи, Р — некоторое положительное число.
Пусть в массиве из 50 записей ключ принимает значения от 0201 до 0250. Выберем Р,= 200. Тогда записи с ключами К = 0211 и К = 0241 будут занимать соответственно 11-ю и 41-ю позиции в массиве.
В случае реальных данных записи массива не всегда имеют последовательные значения ключа и при использовании простейших линейных преобразований часть ячеек памяти останется незанятой. В этих случаях для вычисления адресов используют более сложные функции преобразования — функции хеширования или хеш-функции (от англ. to hash — нарезать, крошить, делать месиво) . Хеш-функция хеширует (т.е. крошит на мелкие кусочки и определенным образом их перемешивает) последовательность цифр или битов, определяющих значение ключа записи или ее кода, в результате чего получается хеш-адрес, по которому записи размещаются и ищутся. Так, например, часто применяемая функция хеширования, реализующая преобразование ключа по методу свертки, разбивает ключ на несколько частей, которые затем суммируются таким образом, чтобы сформировалось число в требуемом диапазоне. Если мы, например, имеем восьмизначные ключи К = 97434658 и К— 31269857 и хотим отобразить их в трехзначные адреса, то можно пр9делать следующие операции:
h (97434658) = 974 + 346 + 58 = 378, h (31269857) = 312 + 698 + 57 = 067.
Здесь символ h означает, что обработку ключа осуществляет хеш-функция. Для того чтобы вычисляемые адреса были трехзначными, сложение производится по модулю 1000. Результатом сложения по mod 1000 является остаток от деления суммы на 1000.
Функция хеширования должна обеспечивать однозначное преобразование ключа записи в ее адрес, причем адреса должны возможно более равномерно распределяться по области памяти, выделенной для хранения данных. В то же время хеш-функция не должна быть слишком сложной, поскольку время, необходимое для преобразований, добавляется к времени выполнения операций ведения, поиска или обработки. Хорошей считается такая хеш-функция, которая быстра и генерирует уникальные и достаточно равномерно распределенные адреса. Однако даже наилучшая хеш-функция не устраняет полностью возможность получения одинаковых адресов. Почти неизбежны коллизии, т.е. ситуации, когда различные записи получают один и тот же адрес. Рассмотрим, как использование одной из наиболее распространенных функций хеширования приводит к возникновению коллизий. Функция основана на методе деления и определяется в виде h (К) =Kmodm+ 1,
где т — делитель. Для вычисления h (К) ключ записи К делится на т и остаток от деления, равный modm, увеличивается на 1. Примем т = 101 и выполним преобразование h (К) над ключами 2000, 2001, ..., 2017. Ключи отобразятся в адреса 82, 83, ..., 99. Эти же самые адреса окажутся сгенерированными функцией h (К) для ключей 3313, 3314, ..., 3330, т.е. возникает коллизия.
Существуют различные методы разрешения коллизий. При использовании одного из них хеш-адрес подвергается рехешированию, заключающемуся в определенных преобразованиях адреса. Например, хеш-адрес, находящийся в коллизии, может быть умножен на константу, в результате чего получится новый адрес. На практике наиболее распространен следующий метод использования вычисленных адресов, позволяющий устранять коллизии. Адрес, генерируемый рандомизирующей процедурой, считается при этом адресом хранения не одной конкретной записи, а области памяти, или страницы памяти, в пределах которой размещаются всё записи, получившие этот адрес. Хеш-функция может генерировать абсолютный адрес страницы или ее номер. В последнем случае создается справочник, в котором номерам страниц ставится в соответствие их абсолютный адрес на ВЗУ или в ОП. Справочник страниц хранится в ОП
