binary diff
От: WolfHound  
Дата: 25.06.05 11:57
Оценка:
Разыскиваются алгоритмы нахождения различий между двумя версиями бинарного файла.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: binary diff
От: conraddk Россия  
Дата: 26.06.05 15:27
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Разыскиваются алгоритмы нахождения различий между двумя версиями бинарного файла.

Re: Сохранение изменений
Автор: conraddk
Дата: 30.11.04
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Все на свете должно происходить медленно и неправильно...
Re: binary diff
От: Alex Alexandrov США  
Дата: 26.06.05 16:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Разыскиваются алгоритмы нахождения различий между двумя версиями бинарного файла.


Поищи в Гугле по bdiff. Первая ссылка на утилиту в исходниках — может, будет полезно.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re[2]: binary diff
От: WolfHound  
Дата: 27.06.05 08:30
Оценка:
Здравствуйте, conraddk, Вы писали:

C>Re: Сохранение изменений
Автор: conraddk
Дата: 30.11.04

Видел я это все. Мне хотелось словесное описание алгоритмов.

C>bsdiff, версия для windows

Слишком медленно.

bsdiff runs in O((n+m) log n) time; on a 200MHz Pentium Pro, building a binary patch for a 4MB file takes about 90 seconds. bspatch runs in O(n+m) time; on the same machine, applying that patch takes about two seconds.

Пусть современные компы будут в 10 раз быстрее но 9 секунд на 4 метра это всеравно много.
C>xdelta
Там чтолько исходников что... к томуже GPL.
C>Binary Diff
Тли там нет исходников толи я не нашол.
C>bdiff
Разбираться в этом хардкоде нет никакого жилания.

Вобщем буду продолжать развивать свой собственный дифф.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: binary diff
От: conraddk Россия  
Дата: 27.06.05 12:21
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

C>>Re: Сохранение изменений
Автор: conraddk
Дата: 30.11.04

WH>Видел я это все. Мне хотелось словесное описание алгоритмов.
В упомянутом RFC есть библиография.

C>>bsdiff, версия для windows

WH>Слишком медленно.
WH>

bsdiff runs in O((n+m) log n) time; on a 200MHz Pentium Pro, building a binary patch for a 4MB file takes about 90 seconds. bspatch runs in O(n+m) time; on the same machine, applying that patch takes about two seconds.

WH>Пусть современные компы будут в 10 раз быстрее но 9 секунд на 4 метра это всеравно много.
Там неплохой алгоритм, основанный на суффиксной сортировке плюс некоторые оптимизации. Для общего случая, на мой взгляд, неплохо. Исходники короткие и относительно простые. Зная о характере изменений в файлах, наверное, можно сделать лучше. Если можно пожертвовать размером патча ради производительности, а объем изменений между версиями невелик, то можно ведь дробить файлы на окна.

WH>Вобщем буду продолжать развивать свой собственный дифф.

Успехов! Получится что интересное — расскажи, если будет возможность.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Все на свете должно происходить медленно и неправильно...
Re[4]: binary diff
От: WolfHound  
Дата: 27.06.05 14:15
Оценка:
Здравствуйте, conraddk, Вы писали:

C>Там неплохой алгоритм, основанный на суффиксной сортировке плюс некоторые оптимизации. Для общего случая, на мой взгляд, неплохо. Исходники короткие и относительно простые. Зная о характере изменений в файлах, наверное, можно сделать лучше. Если можно пожертвовать размером патча ради производительности, а объем изменений между версиями невелик, то можно ведь дробить файлы на окна.

У меня не стоит задача сделать минимальный патч. Нужен алгоритм который выделяет явно дублирующеяся фрагменты и при этом работает быстро.
Размеры файлов на которые все это будет натравливаться от нескольких байт до нескольких гигабайт.

WH>>Вобщем буду продолжать развивать свой собственный дифф.

C>Успехов! Получится что интересное — расскажи, если будет возможность.
В принципе у меня уже есть алгоритм который довольно быстро разгрызает файлы размером болие 4Г (бэкап базы RSDN) но он работает с двумя файлами. Сейчас у меня встала задача сделать тоже самое с несколькими последовательными версиями одного файла.(версий может быть очень много)
Я начал писать свою систему контроля версий. Ну захотелось мне велосипед изобрести.

Я смог адаптировать свой алгоритм который режет два файла но я уперся в тормоза произвольного чтения с винта на больших файлах. Они появляются во время востановления образца из серии патчей. Причем эту проблему нужно както побороть в любом случае ибо доставать файлы будут гораздо чаще чем добовлять новые версии.
И главное требование однажды записаный патч больше никогда не должен меняться иначе посыпится вся остальная механика.

По этому я и написал сюда в надежде что меня пошлют к описаниям других алгоритмов чтобы я смог их проанализировать и возможно выделить полезные мне идеи.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: binary diff
От: mkopachev  
Дата: 28.06.05 06:23
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, conraddk, Вы писали:


C>>Там неплохой алгоритм, основанный на суффиксной сортировке плюс некоторые оптимизации. Для общего случая, на мой взгляд, неплохо. Исходники короткие и относительно простые. Зная о характере изменений в файлах, наверное, можно сделать лучше. Если можно пожертвовать размером патча ради производительности, а объем изменений между версиями невелик, то можно ведь дробить файлы на окна.

WH>У меня не стоит задача сделать минимальный патч. Нужен алгоритм который выделяет явно дублирующеяся фрагменты и при этом работает быстро.
WH>Размеры файлов на которые все это будет натравливаться от нескольких байт до нескольких гигабайт.

WH>>>Вобщем буду продолжать развивать свой собственный дифф.

C>>Успехов! Получится что интересное — расскажи, если будет возможность.
WH>В принципе у меня уже есть алгоритм который довольно быстро разгрызает файлы размером болие 4Г (бэкап базы RSDN) но он работает с двумя файлами. Сейчас у меня встала задача сделать тоже самое с несколькими последовательными версиями одного файла.(версий может быть очень много)
WH>Я начал писать свою систему контроля версий. Ну захотелось мне велосипед изобрести.

WH>Я смог адаптировать свой алгоритм который режет два файла но я уперся в тормоза произвольного чтения с винта на больших файлах. Они появляются во время востановления образца из серии патчей. Причем эту проблему нужно както побороть в любом случае ибо доставать файлы будут гораздо чаще чем добовлять новые версии.

WH>И главное требование однажды записаный патч больше никогда не должен меняться иначе посыпится вся остальная механика.

WH>По этому я и написал сюда в надежде что меня пошлют к описаниям других алгоритмов чтобы я смог их проанализировать и возможно выделить полезные мне идеи.


Я решал такую же задачу, только специфика требовала минимизации пакетов, по-этому требовалось находить самые большие повторяющиеся вхождения. Использовал суффиксную сортировку файла с последующим поиском.
Вообще идеи бродили всякие — часть была испробована, часть нет. Вот то что могу сейчас вспомнить:
— деревья поиска — откровенно не рекомендую — проигрывают суффиксной сортировке на порядок
— суффиксная сортировка (на чем и остановился) — довльно быстро обрабатывает довольно большие файлы (максиальный который пробовался — 10 Мб — 23 сек)
— построение индекса (словаря) по старой версии на основе алгоритма LZ88 (LZW)
— использование контекстно-зависимых вероятностных моделей, и кодирование на основе модели построенной по старому файлу нового файла.

С уважением Михаил Копачев
... << RSDN@Home 1.1.4 @@subversion >>
Re[6]: binary diff
От: WolfHound  
Дата: 28.06.05 07:37
Оценка: 10 (2)
Здравствуйте, mkopachev, Вы писали:

M> Я решал такую же задачу, только специфика требовала минимизации пакетов, по-этому требовалось находить самые большие повторяющиеся вхождения. Использовал суффиксную сортировку файла с последующим поиском.

Я поступил очень просто.
1)Нарезал исходный фаил на блоки одинаковой длинны
2)Посчитал контрольную сумму для каждого блока(причем контрольная сумма не простая, а позволяющая двигатся по последовательности без полного пересчета)
3)Загнал все это в хэш таблицу
Далие двигаю контрольную сумму по новому файлу и произвожу поиск по хэш-таблице. Если совпало то нашли повторяющеяся данные.

Этот алгоритм не очень точен, любит память но меня вполне устраивает ибо работает быстро.
В принципе можно немного повысить точность если при совпадении контрольных сумм проверять не только вперед но и назад. Еще можно сделать так чтобы поиск повторений производился в уже просмотренной части нового файла.
Возможно позже я это реализую ибо это не скажется на скорости востановления файлов.

Сейчас посчитал разницу между двумя файлами весом 10М за 1.5 секунды комп celeron 1.7G. И это при том что там еще можно коечто пооптимизировать.

M> Вообще идеи бродили всякие — часть была испробована, часть нет. Вот то что могу сейчас вспомнить:

Спасибо посмотрю.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: binary diff
От: Chez Россия  
Дата: 29.06.05 07:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Видел я это все. Мне хотелось словесное описание алгоритмов.

WH>Слишком медленно.
WH>Тли там нет исходников толи я не нашол.
WH>Разбираться в этом хардкоде нет никакого жилания.
WH>Там чтолько исходников что... к томуже GPL.
Исходников там не много, правда их надо доводить до ума.
Но я скажу вот что: когда я решал определённую задачу, пришлось потестировать bsdiff, bdiff, guiffy, и ещё чё-то. В общем, остановился именно на Xdelta, т.к. соотношение скорости работы и степени сжатия у XDelta меня приятно порадовало.
Глюков не обнаружено.

WH>Вобщем буду продолжать развивать свой собственный дифф.

Э... а можно мне быть в курсе событий?

Chez, ICQ#161095094

Posted via:RSDN@Home;version:1.1.3;muzikstamp:Paul Mauriat — Reviere

Re[7]: binary diff
От: mkopachev  
Дата: 29.06.05 08:17
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, mkopachev, Вы писали:


M>> Я решал такую же задачу, только специфика требовала минимизации пакетов, по-этому требовалось находить самые большие повторяющиеся вхождения. Использовал суффиксную сортировку файла с последующим поиском.

WH>Я поступил очень просто.
WH>1)Нарезал исходный фаил на блоки одинаковой длинны
WH>2)Посчитал контрольную сумму для каждого блока(причем контрольная сумма не простая, а позволяющая двигатся по последовательности без полного пересчета)
WH>3)Загнал все это в хэш таблицу
WH>Далие двигаю контрольную сумму по новому файлу и произвожу поиск по хэш-таблице. Если совпало то нашли повторяющеяся данные.

WH>Этот алгоритм не очень точен, любит память но меня вполне устраивает ибо работает быстро.

WH>В принципе можно немного повысить точность если при совпадении контрольных сумм проверять не только вперед но и назад. Еще можно сделать так чтобы поиск повторений производился в уже просмотренной части нового файла.
WH>Возможно позже я это реализую ибо это не скажется на скорости востановления файлов.

Я сделал эксперимент, увы такой подход мне не подходит — степнь сжатия падает аж в 2.5 — 3 раза, а мне трафик минимизировать надо . Но работает действительно быстро. Ты какой хэш использовал? Я использовал накапливающуюся сумму по простому модулю. Сначала по 1, потом по 5 разным — получил ускорение примерно в 1.3 раза (правда файл был со множественными периодическими повторениями — они мне больше всего крови портят), дальше замедление пошло . Ты с длиной блока не экспериментировал?

С уважением Михаил Копачев
... << RSDN@Home 1.1.4 @@subversion >>
Re[8]: binary diff
От: WolfHound  
Дата: 29.06.05 09:06
Оценка: 3 (1)
Здравствуйте, mkopachev, Вы писали:

M> Я сделал эксперимент, увы такой подход мне не подходит — степнь сжатия падает аж в 2.5 — 3 раза, а мне трафик минимизировать надо .

Я трафик ZLib'ом минимизировать буду
M>Но работает действительно быстро.
Это мне важно ибо система должна в идеале быть интерактивной.
M>Ты какой хэш использовал? Я использовал накапливающуюся сумму по простому модулю. Сначала по 1, потом по 5 разным — получил ускорение примерно в 1.3 раза (правда файл был со множественными периодическими повторениями — они мне больше всего крови портят), дальше замедление пошло .
Пока такой.
using CheckSumType = System.UInt32;

namespace BinaryDiff
{
    public struct CheckSum
    {
        private static CheckSumType[] table = new CheckSumType[256]
            {
                0xC857A0F3, 0x25030742, 0x821800AA, 0x9D0D0A68, 0xEB6CC802, 0x34C14079, 0xEC453C2E, 0x38F76287,
                0x4D32D266, 0xFF239AA5, 0xCA7AD44E, 0x71B8C3EC, 0x5B49B067, 0x2E0B2EAF, 0x4240211B, 0x3F61AA2B,
                0xD3333B64, 0x927EA4B8, 0x6A8B9DAD, 0x7313585B, 0xF5D9C60E, 0xD273F956, 0x5CDF5F36, 0x86529586,
                0x199C1E41, 0x54426F4D, 0x905410D1, 0x03CC7E04, 0xD87D7D03, 0xA93F9372, 0x4BA189CF, 0x9B256D3C,
                0xCE857CC9, 0xD055E012, 0xA09DBB1A, 0xE0ED1B5A, 0xDB4647BA, 0x02CA52E2, 0x41CFE12A, 0x75154869,
                0x5FE5F357, 0x3E6212A9, 0x7DB944D9, 0x6C5EB531, 0xE93066C4, 0xFDB6A671, 0x49F1703B, 0x8C4C368A,
                0xA28DAECC, 0x1A72D9F2, 0x277F353A, 0xB6C47299, 0xD15F86E6, 0x951264A4, 0xF7220329, 0x62B72A91,
                0x2F9405E4, 0x7B2B6876, 0x31286989, 0xCB2F39FC, 0xBF07176A, 0x049A5421, 0xF05B2973, 0xC2A07520,
                0x8BA2D339, 0x40B16C49, 0xF8FE8796, 0xC505CB52, 0xF43EEC81, 0x2AD3A516, 0xA86519A2, 0xDA904A24,
                0xE526CEDD, 0xBB29799C, 0xD409DAE8, 0x0DC2C0FF, 0x2C17DB27, 0xE6580D8F, 0xF90FF18C, 0x7E1ADD0A,
                0x48D72707, 0x1D7B819B, 0x0E2CB7E5, 0xE43DA13F, 0xB44FC195, 0x97A911FD, 0x1F00B44F, 0x300C1460,
                0x464DA714, 0xAB2D22BF, 0x77DC5585, 0xC73913FA, 0xCDCB9BEB, 0xD9F51526, 0xACC3E9EE, 0x8EB37F7C,
                0x36A6A2D3, 0xE1818EF8, 0x0A86F68E, 0x4398971D, 0xF28FD651, 0xAF1F78BB, 0x17F391F1, 0xC151989E,
                0x600AEEA8, 0x9391BFE3, 0xEF645E28, 0x72BC56A1, 0x518A2040, 0xE8508FDB, 0x67473118, 0xAEA3EF7B,
                0x8441F4D5, 0x21A7F7F4, 0xB2746717, 0x228741BE, 0x4E960FB1, 0x641E7B1F, 0xB5970C0D, 0x8988C9E7,
                0xC67C8D7E, 0x15AA2411, 0x0B20D02C, 0x586A9C82, 0x5DFB99F5, 0xBEEF6EFB, 0xDC53C5AB, 0x11EEE3BC,
                0x809FCF98, 0xD769C290, 0xF635FDC3, 0x9F8E4D25, 0x5AA58CD4, 0x88B45CD2, 0x2DDAED08, 0x29E3E74A,
                0xCF0E2BB3, 0x573A4B01, 0x66370677, 0x6E6E0B22, 0x3911BAC1, 0x33E86578, 0x164438DF, 0xBD0146C5,
                0x7F08DF70, 0x695CDE63, 0x0004D7A6, 0x374A2D37, 0x61750950, 0x058357A3, 0x4C67F5B0, 0x4A92AC47,
                0xC0FFA37F, 0x28C08B93, 0x44F93219, 0x1CA4D1D6, 0x4763CC06, 0x76663EB4, 0x141BCD84, 0xB9BBB96F,
                0x3AD151DC, 0xCCFAB615, 0xEDB0EA4C, 0xB3E0FB58, 0x20F0BD05, 0xAD5A9083, 0x834B8AEA, 0x6D704374,
                0x7931FF7D, 0x7A93F010, 0x7CD61ACD, 0x522AB1DE, 0x3DE437FE, 0x249BC492, 0xA7D52CED, 0x9E06A988,
                0x2B82E645, 0x98B5420B, 0x1E192561, 0x5999A8CB, 0x5021CA80, 0x1BC8602D, 0xB7DD1C13, 0xDE1D235E,
                0x8D77C7F9, 0xC98C3D34, 0x65389EC0, 0xA3EB3335, 0x70277446, 0x9CA86B9D, 0xBA346348, 0xFBBE8823,
                0x3B3B08A7, 0x01CE16E1, 0xF3955AE0, 0xD5F230C7, 0x56E2E81E, 0xBC24F238, 0x26D0710C, 0xF1E60E65,
                0x6FDB859F, 0x532E965C, 0xFE10AB75, 0x08CDE4CA, 0x18D2AFDA, 0x3C804C09, 0x68C96A0F, 0xEABA263D,
                0x9160BC59, 0x747176B9, 0xA69E01EF, 0x13BD73AE, 0xDFFD4F44, 0x8579941C, 0x55162F3E, 0xB068189A,
                0x87E97A7A, 0x1259B3B6, 0xEEABEB6C, 0xE2435B6B, 0x0CD4FA54, 0x066BDCB5, 0x636F828B, 0x32ADD833,
                0xD6EC9F97, 0xE3BFB8E9, 0x9936618D, 0x5EDE025D, 0xAA76ADC6, 0x071C3A43, 0xA548E5F0, 0xC3FCFEB7,
                0x9A78D562, 0xB1D8596E, 0xFA5604F6, 0x94C7832F, 0x23AF49CE, 0x10C6B26D, 0x966D8055, 0xB84E4ED8,
                0x0FAE4500, 0x09F63F30, 0xFCEA53B2, 0x78E7E2F7, 0x8FF81FC2, 0x453CFCBD, 0xA1B284AC, 0x6BAC92D7,
                0xA402BE53, 0x4F84F85F, 0xDD5D5032, 0xC4E13494, 0xE7891DA0, 0x35F4284B, 0x811477D0, 0x8AC55DC8,
        };

        private CheckSumType hi;
        private CheckSumType lo;

        public void Init(byte[] arr, int ofs, int size)
        {
            unchecked
            {
                hi = 0u;
                lo = 0u;
                size += ofs;
                for (int i = ofs; i < size; ++i)
                {
                    lo += table[arr[i]];
                    hi += lo;
                }
            }
        }

        public void Increment(byte include, byte exlude, int size)
        {
            unchecked
            {
                CheckSumType e = table[exlude];
                CheckSumType i = table[include];
                lo -= e;
                lo += i;
                hi -= e * ((CheckSumType) size);
                hi += lo;
            }
        }

        public override int GetHashCode()
        {
            unchecked
            {
                CheckSumType hash = lo ^ hi;
                hash ^= hash >> 7;
                hash ^= hash >> 11;
                hash ^= hash >> 13;
                return (int) (hash & 0x7fffffffu);
            }
        }

//        public override bool Equals(object obj)
//        {
//            if (obj is CheckSum)
//            {
//                CheckSum sum = (CheckSum) obj;
//                return Equals(ref sum);
//            }
//            else
//                return false;
//        }

        public bool Equals(ref CheckSum that)
        {
            return (lo == that.lo) && (hi == that.hi);
        }

//        public static bool operator ==(CheckSum l, CheckSum r)
//        {
//            return l.Equals(ref r);
//        }
//
//        public static bool operator !=(CheckSum l, CheckSum r)
//        {
//            return !l.Equals(ref r);
//        }
    }
}

Я тут проверил на >500 метровых файлах эта контрольная сумма промахнулась всего 12 раз . И справляется она с ними за 4 с половиной минуты.

M>Ты с длиной блока не экспериментировал?

Он у меня плавает в зависимости от размера файла и доступной памяти.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: binary diff
От: WolfHound  
Дата: 29.06.05 09:41
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>И справляется она с ними за 4 с половиной минуты.

В смысле не контрольныя сумма, а дифф.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.