Есть ли у кого-нибудь реализация алгоритма генерации бинарных патчей на C#?
По сути, сравните два файла (обозначенные Старый и новый) и создайте файл исправления, который можно использовать для обновления файла Старый, чтобы он имел то же содержимое, что и файл новый.
Реализация должна быть относительно быстрой и работать с огромными файлами. Он должен показывать время выполнения O (n) или O (logn).
Мои собственные алгоритмы имеют тенденцию быть либо паршивыми (быстрыми, но производят огромные исправления), либо медленными (производят небольшие исправления, но имеют время выполнения O (n ^ 2)).
Любые советы или указатели по реализации были бы хороши.
В частности, реализация будет использоваться для синхронизации серверов для различных больших файлов данных, для которых у нас есть один главный сервер. При изменении файлов данных главного сервера нам также необходимо обновить несколько внешних серверов.
Самый наивный алгоритм, который я сделал, который работает только с файлами, которые могут храниться в памяти, выглядит следующим образом:
Это чем-то похоже на сжатие без использования окон, поэтому для этого потребуется много памяти. Однако это довольно быстро и производит довольно маленькие патчи, если я стараюсь сделать вывод кода минимальным.
Алгоритм с более эффективным использованием памяти использует окна, но производит файлы исправлений гораздо большего размера.
В описанном выше алгоритме есть больше нюансов, которые я пропустил в этом посте, но при необходимости я могу опубликовать более подробную информацию. Однако я чувствую, что мне нужен совсем другой алгоритм, поэтому улучшение вышеупомянутого алгоритма, вероятно, не приведет меня достаточно далеко.
Редактировать # 1: Вот более подробное описание вышеуказанного алгоритма.
Сначала объедините два файла, чтобы получился один большой файл. Запомните точку разделения между двумя файлами.
Во-вторых, сделайте этот шаг возьмите 4 байта и добавьте их позицию в словарь для всего во всем файле.
В-третьих, с того места, где начинается файл новый, выполните цикл с попыткой найти существующую комбинацию из 4 байтов и найти самое длинное совпадение. Убедитесь, что мы учитываем только позиции из старого файла или из раньше в новом файле, чем мы сейчас. Это гарантирует, что мы можем повторно использовать материал как в старом, так и в новом файле во время применения патча.
Редактировать # 2: Исходный код вышеуказанного алгоритма
Вы можете получить предупреждение о проблемах с сертификатом. Я не знаю, как решить эту проблему, поэтому пока просто примите сертификат.
В источнике используется множество других типов из остальной части моей библиотеки, так что этот файл - это не все, что нужно, но это реализация алгоритма.
@lomaxx, я попытался найти хорошую документацию по алгоритму, используемому в Subversion, который называется xdelta, но если вы еще не знаете, как работает алгоритм, найденные мной документы не могут сказать мне то, что мне нужно знать.
А может я просто тупой ... :)
Я быстро взглянул на алгоритм с того сайта, который вы дали, и, к сожалению, его нельзя использовать. Комментарий из двоичного файла diff гласит:
Finding an optimal set of differences requires quadratic time relative to the input size, so it becomes unusable very quickly.
Однако мои потребности не оптимальны, поэтому я ищу более практичное решение.
Спасибо за ответ, добавил закладку в свои утилиты, если они мне когда-нибудь понадобятся.
Редактировать # 1: Обратите внимание, я посмотрю на его код, чтобы узнать, смогу ли я найти какие-то идеи, а также позже отправлю ему электронное письмо с вопросами, но я прочитал ту книгу, на которую он ссылается, и хотя решение хорошо подходит для поиска оптимального решения, это непрактично в использовании из-за требований времени.
Редактировать # 2: Я обязательно найду реализацию python xdelta.
Этот конкретный фрагмент кода является публикацией, вот моя текущая версия, хотя я давно не поддерживал эту библиотеку: lassevk.kilnhg.com/Code/LVK-for-NET/net-40/trunk/Files/…





Возможно, стоит проверить, что некоторые другие ребята делают в этой сфере, и не обязательно на арене C#.
Это библиотека, написанная на C#
SVN также имеет алгоритм двоичного сравнения, и я знаю, что есть реализация на python, хотя я не смог найти его с помощью быстрого поиска. Они могут подсказать вам, где улучшить собственный алгоритм.
SVN использует алгоритм xdelta (по крайней мере, если посмотреть на источник)
Извини, я ничем не мог больше помочь. Я определенно продолжу смотреть на xdelta, потому что я использовал его несколько раз для создания качественных различий в файлах ISO размером 600 МБ +, которые мы сгенерировали для распространения наших продуктов, и он работает очень хорошо.
Да, xdelta хороша. Однако он работает с относительно небольшими окнами (100 КБ, если я не ошибаюсь), но с его рабочей реализацией я мог бы легко настроить это для наших данных. Размер окна был выбран для скорости подрывной деятельности, если я не ошибаюсь, но наш код может легко работать немного дольше, если это не должно занимать всю ночь (что и делает моя текущая реализация).
Если это для установки или распространения, рассматривали ли вы использование пакета SDK для установщика Windows? Он имеет возможность исправлять двоичные файлы.
http://msdn.microsoft.com/en-us/library/aa370578(VS.85).aspx
Вы видели VCDiff? Это часть довольно активной библиотеки Misc (последний выпуск r259, 23 апреля 2008 г.). Я не использовал его, но подумал, что стоит упомянуть.
Это приблизительная рекомендация, но ниже приводится алгоритм rsync, который можно использовать для создания ваших двоичных патчей.
bsdiff был разработан для создания очень маленьких патчей для двоичных файлов. Как указано на его странице, он требует max(17*n,9*n+m)+O(1) байт памяти и работает во времени O((n+m) log n) (где n - это размер старого файла, а m - размер нового файла).
Исходная реализация находится на C, но порт C# описан здесь и доступен здесь.
Ссылка на исходный код мертва. Можете ли вы обновить его?