Найти то, что было изменено и загрузить только изменения - PullRequest
8 голосов
/ 05 ноября 2010

Я просто ищу идеи / предложения здесь;Я не прошу полного решения (хотя, если у вас есть, я был бы рад взглянуть на него)

Я пытаюсь найти способ только загрузить изменения в текст.Скорее всего, оно будет использоваться в качестве облачного приложения, работающего на jQuery и HTML, с PHP-сервером, работающим на стороне сервера.

Например, если у меня есть текст типа

asdfghjklasdfghjkl

И я изменяю его на

asdfghjklXasdfghjkl

Я не хочу загружать все целиком (текст может стать довольно большим)

Например, что-то вроде 8,Xотправлено на сервер может означать: add an X to the 8th position

Или D8,3 может означать: go to position 8 and delete the previous 3 terms

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

Так что спасибо, что прочитали это.Вот краткое изложение того, что нужно для предложений

  • Обнаружение изменений / модификаций
  • Способ сообщения об изменениях
  • Восстановление после повреждения
  • Все остальноечто нуждается в улучшении

Ответы [ 3 ]

4 голосов
/ 05 ноября 2010

Уже существует принятая форма для передачи такого рода информации о различиях. Это называется Unified Diff .

google-diff-match-patch предоставляет реализации на Java, JavaScript, C ++, C #, Lua и Python.

Вы должны иметь возможность просто сохранить «исходный текст» и «измененный текст» в переменных на клиенте, затем сгенерировать diff в javascript (через diff-match-patch), отправить его на сервер вместе хеш и восстановите его (используя diff-match-patch или unix "patch" программу) на сервере.

Вы также можете рассмотреть возможность включения «версии» (или измененной даты), когда вы отправляете исходный текст клиенту в первую очередь. Затем включите ту же версию (или дату) в «запрос diff», который клиент отправляет на сервер. Проверьте версию на сервере перед применением diff, чтобы быть уверенным, что копия текста на сервере не отклонилась от копии клиента во время внесения изменений. (конечно, чтобы это работало, вам нужно будет обновлять номер версии на сервере каждый раз, когда обновляется основная копия).

1 голос
/ 05 ноября 2010

Это звучит как проблема, которую системы контроля версий (CVS, SVN, Git, Bazaar) уже решают очень хорошо.

Все они достаточно просты в настройке на сервере, и вы можете общаться с ними через PHP.

После установки вы получите бесплатно: управление версиями, журнал, откат, обработку одновременных изменений, правильный синтаксис различий, тегирование, ветки ...

Вы не получите запрашиваемую функцию «отправлять только обновления». Я не уверен, насколько это важно для вас. Чистые тексты действительно очень дешевы для отправки, если говорить о пропускной способности.

Лично я, вероятно, пошел бы на компромисс, подобный тому, что делают вики. Разбейте весь текст на более мелкие семантически согласованные фрагменты (главы или даже абзацы), определите на стороне клиента, какие именно фрагменты были отредактированы (без перехода на уровень символов), и отправьте их.

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

Еще один общий намек может состоять в том, чтобы посмотреть, что Google сделал с Wave. Я должен оставаться здесь общим, потому что сам на самом деле не изучал это подробно, но я, кажется, помню, что было несколько статей о том, как они решили проблему одновременного редактирования в реальном времени, которая, кажется, точно что бы ты хотел сделать.

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

1 голос
/ 05 ноября 2010

У вас действительно интересный подход. Но если текстовые файлы действительно настолько велики, что для их загрузки каждый раз требуется слишком много времени, почему вы отправляете все это клиенту? Клиент действительно должен получить весь текстовый файл 5 МБ? Разве нельзя было отправить ему только то, что ему нужно?

В любом случае, на ваш вопрос: Первое, что приходит мне в голову, когда я слышу «большие текстовые файлы» и обнаружение модификации, это diff . Для алгоритма прочитайте здесь . Это может быть подход для фиксации изменений, и он определяет формат для него. Вам просто нужно перестроить diff (или его часть) в javascript. Это будет непросто, но возможно, как я полагаю. Если алгоритм вам не помогает, возможно, по крайней мере определение формата файла diff поможет.

К вопросу о повреждении: вам не нужно опасаться, что ваша дата будет повреждена в пути, потому что протокол TCP, на котором основан HTTP, выглядит так, что все приходит без повреждений. Чего вам следует бояться, так это сброса соединения. Может быть, вы можете сделать что-то вроде рукопожатия? Когда клиент отправляет обновление на сервер, сервер применяет изменения и сохраняет одну старую версию файла. Чтобы убедиться, что клиент получил от сервера подтверждение о том, что изменение прошло успешно (именно здесь происходит сброс соединения), клиент отправляет на сервер другой запрос ajax. Если этот файл не приходит на сервер в течение определенного времени, файл сбрасывается на стороне сервера.

Другое дело: я не знаю, нравится ли javascript обрабатывать такие гигантские файлы / данные ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...