Искусство программирования для Unix
Шрифт:
#
Цель данного инструментального средства — позволить пользователю редактировать различные непонятные типы PNG-блоков, которые вовсе не обязательно поддерживаются традиционными графическими редакторами. Вместо написания специализированного кода для анализа двоичного PNG-формата, пользователь может просто преобразовать изображение в полнотекстовое представление, отредактировать его, а затем переконвертировать его обратно. Другая потенциальная прикладная задача заключается в том, чтобы сделать изображение открытым для
Однако выигрыш в данном случае связан не только со временем, не потраченным на написание специализированного кода для манипуляций с двоичными PNG-файлами. Код программы sng не является очень прозрачным, однако он поддерживает прозрачность в более крупных системах программ, делая все содержимое PNG-файлов воспринимаемым.
6.1.6. Учебный пример: база данных Terminfo
База данных terminfo представляет собой набор описаний видеотерминалов. В каждой записи описываются escape-последовательности, которые осуществляют различные операции на экране терминала, такие как вставка или удаление строк, удаление символов от курсора до конца строки или экрана, или начало и завершение подсветки экрана, такой как негативное видеоизображение, подчеркивание или мерцание.
База данных terminfo главным образом используется библиотеками curses(3), которые лежат в основе rogue-подобного стиля интерфейса, описанного в главе 11, и некоторых широко используемых программ, таких как mutt(1), lynx(1) и slrn(1). Хотя эмуляторы терминалов, такие как xterm(1), работающие на современных растровых дисплеях, обладают всеми возможностями, которые незначительно отличаются от возможностей стандарта ANSI X3.64 и устаревших терминалов VT100, существует достаточно много таких разновидностей терминалов, где жесткая привязка приложения к ANSI-возможностям была бы плохой идеей. База данных terminfo также достойна рассмотрения, ввиду того, что проблемы, логически подобные проблемам, которые решаются terminfo, постоянно возникают в управлении другими видами периферийного аппаратного обеспечения, не имеющего стандартного способа предоставления информации о собственных характеристиках.
В конструкции terminfo учтен опыт более раннего формата описания характеристик, который называется termcap. База данных termcap-описаний в текстовом формате содержалась в одном большом файле,
Обычно ключом, используемым для поиска записи о типе терминала, является переменная среды
60
Фактически переменная
Практика работы с termcap показала, что на задержку при запуске доминирующее влияние оказывало время, необходимое для синтаксического анализа текстовой формы представления характеристик. Поэтому terminfo-записи являются копиями двоичных структур, для которых операции маршалинга и демаршалинга выполняются быстрее. Существует главный текстовый формат для всей базы данных, файл характеристик terminfo. Данный файл (или отдельные записи) можно преобразовать в двоичную форму с помощью terminfo-компилятора tic(1), а бинарные записи декомпилируются в редактируемый текстовый формат посредством утилиты infocmp(1).
Такая конструкция внешне противоречит данным в главе 5 рекомендациям против использования двоичного кэширования, однако, в сущности, это тот экстремальный случай, в котором данный подход является хорошей тактикой. Главные текстовые файлы редактируются очень редко — в действительности Unix-системы обычно поставляются с предварительно скомпилированной базой данных terminfo, а главный текстовый файл служит в основном в качестве документации. Следовательно, проблемы синхронизации и несогласованности, которые обычно препятствуют реализации такого подхода, почти никогда не возникают.
Проектировщики terminfo могли бы оптимизировать скорость другим путем. Вся база данных бинарных записей могла бы размещаться в некотором большом трудном для понимания файле базы данных. Однако они выбрали более мудрое решение, которое к тому же больше соответствовало бы духу операционной системы Unix. Записи terminfo располагаются в иерархии каталогов, обычно в современных Unix-системах в каталоге /usr/share/terminfo. Точное расположение базы данных в конкретной системе можно выяснить с помощью страницы документации terminfo(5).
Изучая каталог terminfo, можно заметить, что в качестве имен подкаталогов используются одиночные печатаемые символы. В каждом подкаталоге находятся записи для всех типов терминалов, имена которых начинаются с данной буквы. Цель такой организации заключалась в том, чтобы избежать необходимости выполнять линейный поиск в очень большом каталоге. В более современных файловых системах Unix, которые представляют каталоги с помощью бинарных деревьев или других структур, оптимизированных для быстрого поиска, подкаталоги не являются необходимыми.
Я выяснил, что даже в довольно современных Unix-системах разделение большого каталога на подкаталоги может существенно повысить производительность. На поздней модели DEC Alpha, использующей DEC Unix, были десятки тысяч файлов базы данных авторизованных пользователей для крупного образовательного учреждения. (Из всех протестированных схем наилучшим образом функционировали подкаталоги с именами, состоящими из первой и последней букв фамилии, например, записи для "johnson" находились бы в каталоге "j_n". Использование первых двух букв было не настолько эффективным, поскольку было множество систематически создаваемых имен, которые отличались только окончанием.) Это, возможно, говорит только о том, что сложное индексирование каталогов до сих пор является не таким распространенным, каким должно было бы быть... Однако даже в этом случае оно делает организацию, хорошо работающую без него, более переносимой, чем та, которая в нем нуждается.
Таким образом, издержки открытия terminfo-записи сводятся к двум операциям поиска в файловой системе и открытию файла. Но поскольку извлечение той же записи из одной большой базы данных потребовало бы поиска и открытия базы данных, инкрементальные издержки организации terminfo равны максимум одной операции поиска в файловой системе. Фактически они меньше. Существует разница затрат между одной операцией поиска в файловой системе и каким бы то ни было методом поиска, применяемым в одной большой базе данных. Однократное использование такого метода при запуске приложения, вероятно, не влечет серьезных последствий и вполне допустимо.