EN · DE · RU · FR · ES

#1873: DiffMatchPatch.java

projectforge-common/src/main/java/name/fraser/neil/plaintext/DiffMatchPatch.java Biblioteca de terceros (incrustada) — Google diff-match-patch, projectforge-common/src/main/java/name/fraser/neil/plaintext/DiffMatchPatch.java 2464 líneas · 1638 código · 688 comentarios · 138 en blanco
La biblioteca de algoritmos diff-match-patch de Google, de Neil Fraser, incrustada directamente en ProjectForge bajo el paquete original name.fraser.neil.plaintext. Licenciada bajo Apache License 2.0. Proporciona comparación de texto síncrona (diff), coincidencia difusa (match) y aplicación de parches (patch) — los mismos algoritmos que impulsan Google Docs, Etherpad y la comparación de revisiones de Wikipedia. Utilizada por ProjectForge para el seguimiento de cambios de texto y comparación de versiones.

Arquitectura

Origen y Licencia

Resumen del Algoritmo

La biblioteca implementa tres algoritmos relacionados, todos operando sobre texto plano:

1. Diff — Algoritmo de Diferencias O(ND) de Myers

Calcula el conjunto mínimo de ediciones para transformar texto1 en texto2. El algoritmo central es el algoritmo diff de Myers (1986), que encuentra el script de edición más corto utilizando un enfoque O(ND) en tiempo/espacio, donde N es la suma de las longitudes de las cadenas y D es el número de diferencias.

2. Match — Algoritmo Bitap (Shift-Or)

Localiza la mejor coincidencia aproximada para un patrón dentro de un texto más grande. Utiliza el algoritmo Bitap (también conocido como shift-or o algoritmo Baeza-Yates–Gonnet) que:

3. Patch — Formato Diff Unificado + Aplicación Difusa

Crea parches (representaciones textuales de diffs) que pueden ser serializados, transmitidos y aplicados a otros textos:

Parámetros Clave de Configuración

CampoValor por defectoPropósito
Diff_Timeout1.0 segundosSegundos máximos para un cálculo diff antes de devolver un resultado parcial (0 = infinito)
Diff_EditCost4Costo de una operación de edición vacía — valores más altos producen diffs más limpios y menos fragmentados
Match_Threshold0.5Umbral de coincidencia difusa (0.0 = exacto, 1.0 = muy flexible)
Match_Distance1000Bonificación de localidad — distancia en caracteres desde la ubicación de coincidencia esperada
Patch_DeleteThreshold0.5Qué tan cerca deben coincidir los bloques eliminados con el contenido esperado para ser aceptados
Patch_Margin4Número de caracteres de contexto alrededor de los fragmentos del parche
Match_MaxBits32Ancho de bits para el algoritmo Bitap (coincide con el tamaño de int en Java)

Estructura de Datos: Diff (Clase Interna)

Los diffs se representan como un LinkedList<Diff> donde cada Diff es una clase interna estática con:

Ayudante Interno: LinesToCharsResult

Una optimización para textos grandes: convierte líneas en caracteres Unicode únicos, realiza el diff en la representación comprimida y luego reconstruye la salida a nivel de línea. Esto reduce drásticamente el espacio de comparación para texto orientado a líneas (por ejemplo, código fuente).

Importaciones

Uso en ProjectForge

ProjectForge incrusta esta biblioteca en lugar de depender de ella como un JAR externo. Esto probablemente se hizo porque:

  1. La biblioteca es estable y rara vez cambia (la última actualización significativa fue el puerto a Java alrededor de 2010)
  2. La incrustación evita problemas de gestión de dependencias
  3. El nombre del paquete (name.fraser.neil.plaintext) es distintivo y no entra en conflicto
  4. Puede tener modificaciones personalizadas para necesidades específicas de ProjectForge (aunque el código parece ser el puerto estándar)
DiffMatchPatch se utiliza para rastrear cambios en campos de texto en los objetos de datos de ProjectForge — mostrando qué cambió entre versiones de una dirección, descripción de proyecto u otro contenido de texto.

La biblioteca ha sido portada a múltiples lenguajes (Python, JavaScript, Java, C++, C#, Lua, Dart). La versión Java utiliza LinkedList para el almacenamiento de diffs porque los diffs se recorren principalmente de forma secuencial (no acceso aleatorio) y el algoritmo frecuentemente antepone/añade elementos.

Historial de Git

48a93dedb Registro de consola coloreado. UserGroupCache exportado para depuración y comparación de trabajo ahora. CollectionUtil mejorado. KotlinStringExtension.shortenMiddle() añadido.