Анимация
JavaScript
|
Главная Библионтека 14.6. Сортировка больших DBM-файлов Проблема Необходимо обработать большой объем данных, которые должны передаваться в DBM-файл в определенном порядке. Решение Воспользуйтесь возможностью связывания В-деревьев модуля DB File и предоставьте функцию сравнения: use OB File; # Указать функцию Perl, которая должна сравнивать ключи # с использованием экспортированной ссылки на хзш $OB BTREE $DB BTREE->{compare} = sub { my ($key1, $кеу2) = @ ; \L$key1" cmp •\L$key2" ; tie(%hash, OB File", Sfilename, 0 ROWR0 CREAT, 0666, $DB BTREE) or die "cant tie Sfilename: S!"; Комментарий Основной недостаток хэшей (как в памяти, так и в DBM-файлах) заключается в том, что они не обеспечивают нормального упорядочения элементов. Модуль Tie::IxHash с CPAN позволяет создать хэш в памяти с сохранением порядка вставки, но это не поможет при работе с базами данных DBM или произвольными критериями сортировки. Модуль DB File содержит изящное решение этой проблемы за счет использования В-деревьев. Одно из преимуществ В-дерева перед обычным DBM-хэшем - его упорядоченность. Когда пользователь определяет функцию сравнения, любые вызовы keys, values и each автоматически упорядочиваются. Так, программа из примера 14.4 создает хэш, ключи которого всегда сортируются без учета регистра символов. Пример 14.4. sortdemo #!/usr/bin/perl # sortdemo - автоматическая сортировка dbm use strict; use DB File; $DB BTREE->r compare} = sub { my (Skeyl, Skey2) = @> ; "XLSkeyl" cmp "\L$key2" ; my %hash; my Sfilename = /tmp/sorthash.db; 14.7. Интерпретация текстового файла в виде строковой базы данных 507 tie(%hash, DB.File-, Sfilename, 0 ROWR0 CREAT, 0666, $DB BTREE) or die "cant tie Sfilename: S!"; my Si = 0; for my Sword (qw(Cant you go camp down by Gibraltar)) { ShashfSword} = ++Si; while (myCSword, Snumber) = each %hash) { printf "%-12s %d\n". Sword, Snumber; По умолчанию записи баз данных В-деревьев DB File сортируются но алфавиту. Однако в данном случае мы написали функцию сравнения без учета регистра, поэтому применение each для выборки всех ключей даст следующий результат: by 6 camp 4 Cant 1 down 5 Gibraltar 7 go 3 you 2 Эта возможность сортировки хэща настолько удобна, что ей стоит пользоваться даже без базы данных на диске. Если передать tie вместо имени файла undef, DB File создаст файл в каталоге /tmp, а затем немедленно уничтожит его, создавая анонимную базу данных: tie(%hash, "DB.File", undef, 0 RDWR0 CREAT, 0666, $DB BTREE) or die "cant tie: S!"; Обеспечивая возможность сравнения для своей базы данных в виде В-дерева, необходимо помнить о двух обстоятельствах. Во-первых, при создании базы необходимо передавать новую функцию сравнения. Во-вторых, вы не сможете изменить порядок записей после создания базы; одна и та же функция сравнения должна использоваться при каждом обращении к базе. Базы данных BTREE также допускают использование повторяющихся или неполных ключей. За примерами обращайтесь к документации. > Смотри также- Рецепт 5.6. 14.7. Интерпретация текстового файла в виде строковой базы данных Проблема Требуется организовать работу с текстовым файлом как с массивом строк с привилегиями чтения/записи. Например, это может понадобиться для того, чтобы вы могли легко обновить N-ю строку файла. Решение Модуль DB File позволяет связать текстовый файл с массивом, use DB Flle; tie(@>array, "DB.File", Vtmp/textflle", 0 RDWR0 CREAT, 0666, $DB RECNO) or die "Cannot open file text: $!\en" ; $array[4] = "a new line"; untie ©array; Комментарий Обновление текстового файла на месте может оказаться на удивление нетривиальной задачей (см. главу 7 «Доступ к файлам»). Привязка REGNO позволяет удобно работать с файлом как с простым массивом строк - как правило, все полагают, что именно этот вариант является наиболее естественным. Однако этот способ работы с файлами отличается некоторыми странностями. Прежде всего, нулевой элемент связанного массива соответствует первой строке файла. Еще важнее то, что связанные массивы не обладают такими богатыми возможностями, как связанные хэщи. Положение будет исправлено в будущих версиях Perl - в сущности, «заплаты» существуют уже сейчас. Как видно из приведенного выше примера, интерфейс связанного массив:! о-раничен. Чтобы расширить его возможности, методы DB File имитируют м i дартные операции с массивами, в настоящее время не реализованные в ими фейс связанных массивов Perl. Сохраните значение, возвращаемое функцией tie, или получите его позднее для связанного хэша функцией tied. Для этого объекта можно вызывать следующие методы: $X->push(CnMCOK) Заносит элементы списка в конец массива. Svalue = $Х->рор Удаляет и возвращает последний элемент массива. $X->shift Удаляет и возвращает первый элемент массива. SX->unshift(CnMCOK) Заносит элементы списка в начало массива. $X->length Возвращает количество элементов в массиве. Пример 14.5 показывает, как все эти методы используются на практике. Кроме того, он работает с интерфейсом API так, как рассказано в документации модуля DB File (большая часть рецепта позаимствована из документации DB file с согласия Пола Маркесса, автора Perl-порта Berkeley DB; материал использован с его разрешения). 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 [ 163 ] 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |