?

Log in

No account? Create an account

Заповедник репрессивной психиатрии

Таки новый год я проработал
metaclass
Сидел козлопитонировал алгоритм, избавился от замедления алгоритма кэширования, но пришел к выводу, что в существующем виде его использовать в продакшене все равно нельзя - время отклика совершенно неравномерное, от нескольких секунд до десятков минут, в зависимости от того, как часто вызывался этот алгоритм и сколько между вызовами меняли данные в базе.

О психах и Unicode
metaclass
Подкинули безумную задачку - есть бинарный файл-словарь. Нужно из него вытащить список слов и вставить в другой словарь.
Ну сел разбираться. Вижу - классика, в начале файла гигантский индекс из записей постоянной структуры с указателями(они на глаз хорошо видны, периодическая структура), после него идут список слов, слова переменной длины. Задача простейшая - определить длину и формат записи индекса, вычитать слова и сохранить в что-то более вменяемое.
Слова в юникоде, и самое главное - в начале файла есть unicode byte order mark(FFFE).
Высчитал длину записи индекса, сдампил его с длиной строки равной длине записи, и смотрю - ну что-то странное откровенно. Вижу что нарастающие указатели, вижу что данные бинарные, но при этом - формат явно уникод, т.е. байт, 0, байт, 0, иногда байт,20, итд.
Ну ладно, сначала думаю, найду где длина слова живет. Взял три слова с начала, посчитал длину, сразу же увидел где она в индексе. Решил почитать пока чисто через длину слова. Фиг, иногда соскакивает позиция, видимо какие-то дополнительные флаги к слову добавлены. В процессе осмысления смотрю на первые восемь байт индекса и вижу что в натуре из них получается указатель на слово, если их умножить на 2 и прибавить 2. Но не всегда. Иногда спрыгивает в дебри куда-то. И старшие два байта вместо 0000 - 2000.

Оказывается, психи, которые писали файл, писали в него бинарные данные побайтно, не отключив конверсию этого дела в юникод. Т.е. каждые 9 байт индекса записывались как 18 байт записи в файле с конверсией странных символов из текущей локали в соответствующие юникодные. И конверсией 00 в пробел, т.е. 00 - 2000.
Вуду-программирование. Сказали людям "сделать юникод-версию", они заменили функции на соответствующие юникодные и все :)
Пришлось составить список юникодных символов, сопоставить методом анализа файла их реальным байтам и написать конвертор. При этом байты 20 и 00 в выходном файле формально неразличимы, пришлось добавить эмпирический анализатор который ищет правильное значение по критерию типа "следующий индекс должен отличаться от предыдущего на длину слова")