Comparación eficiente de DAG en una red

11

En los sistemas de control de versiones distribuidas (como Mercurial y Git ) existe la necesidad de comparar eficientemente los gráficos acíclicos dirigidos (DAG). Soy un desarrollador de Mercurial, y estaríamos muy interesados ​​en escuchar sobre el trabajo teórico que discute la complejidad del tiempo y la red de comparar dos DAG.

Los DAG en cuestión están formados por las revisiones registradas. Las revisiones se identifican de forma exclusiva por un valor hash. Cada revisión depende de cero (confirmación inicial), una (confirmación normal) o más (confirmación de fusión) de las revisiones anteriores. Aquí es un ejemplo donde las revisiones aa ese hicieron una después de la otra:

a --- b --- c --- d --- e

La comparación gráfica aparece cuando alguien tiene solo una parte del historial y quiere recuperar la parte que falta. Imagínese que tenía aa ce hice xy ybasándonos en c:

a --- b --- c --- x --- y

En Mercurial, haría hg pully descargaría dy e:

a --- b --- c --- x --- y
              \
                d --- e

El objetivo es identificar dy eeficientemente cuando el gráfico tiene muchos (digamos, más de 100,000) nodos. La eficiencia concierne a ambos

  • complejidad de la red: la cantidad de bytes transferidos y la cantidad de viajes de ida y vuelta necesarios
  • complejidad de tiempo: la cantidad de cómputo realizado por los dos servidores que intercambian conjuntos de cambios

Los gráficos típicos serán estrechos con pocas pistas paralelas como las anteriores. Por lo general, solo habrá un puñado de nodos hoja (los llamamos cabezas en Mercurial) como ey por yencima. Finalmente, cuando se usa un servidor central, el cliente a menudo tendrá un par de conjuntos de cambios que no están en el servidor, mientras que el servidor puede tener más de 100 conjuntos de cambios nuevos para los clientes, dependiendo de quién hace mucho tiempo que el cliente se retiró del servidor por última vez . Se prefiere una solución asimétrica : un servidor centralizado debería hacer pocos cálculos en comparación con sus clientes.

Martin Geisler
fuente
La discusión ha continuado un poco en Google Plus .
Martin Geisler

Respuestas:

13

En este contexto, los nodos del gráfico tienen algún tipo de identificador único (un hash o suma de comprobación), ¿verdad? Por lo tanto, no necesita hacer ningún tipo de prueba de isomorfismo de subgrafo, solo necesita una lista de los nodos que difieren entre sus dos versiones, y los bordes no son realmente útiles para este paso. Mi documento SIGCOMM 2011 " ¿Cuál es la diferencia? Conciliación eficiente de conjuntos sin contexto previo"(con Goodrich, Uyeda y Varghese) considera exactamente este problema: resulta que puede determinar las identidades de los nodos que están en poder de uno pero no de los dos servidores de comunicación, utilizando una cantidad de comunicación que es proporcional solamente a la cantidad de nodos modificados y utilizando solo un solo viaje de ida y vuelta Una vez que tenga esa información, es fácil extraer los cambios en un segundo viaje de ida y vuelta, nuevamente con una comunicación óptima.

David Eppstein
fuente
Uh, esto suena interesante! Tiene razón en que una comparación directa de los ID del conjunto de cambios (sí, son valores hash) funcionará. Siempre tratamos de usar la estructura gráfica también: si ambos conocemos X, entonces también sé que conoces a todos los antepasados ​​de X. Parece información importante, pero tal vez no lo sea. Leeré tu periódico ahora, ¡gracias por el puntero!
Martin Geisler
@David: una precisión (soy uno de los autores del algoritmo utilizado actualmente por Mercurial). En realidad nos importa el conjunto de nodos "comunes", no es necesario saber el valor del nodo que falta.
tonfa
1
Si sabes lo que es diferente, entonces también sabes lo que hay en común: todo lo que tienes una copia no es parte de la diferencia. Pero la diferencia generalmente debería ser relativamente pequeña, incluso cuando la parte común es grande, por lo que es mejor comunicar solo una cantidad de datos proporcionales a la diferencia que comunicar todo el DAG del historial o la parte común.
David Eppstein
@David: debido a la relación ancestral, en realidad calculamos las cabezas (nodos de hoja) de la región común. De modo que todavía es una pequeña cantidad de datos, incluso si hay un gran historial compartido.
Martin Geisler
Actualicé mi respuesta para incluir también el número de viajes de ida y vuelta utilizados (que resulta ser muy pequeño).
David Eppstein
3

En la solución que implementamos para Mercurial, otra preocupación era la asimetría: la carga del servidor debería minimizarse tanto para el ancho de banda saliente como para el tiempo de CPU, a costa de la carga del cliente.

Peter Arrenbrecht
fuente
1
Gracias, he actualizado un poco la pregunta para notar esto.
Martin Geisler
0

Suena como un proceso de dos pasos para mí.

  1. preguntar a todos los clientes si tienen compromisos donde el padre es c
  2. si es así, encuentre todos los hijos de c

La tarea de 1. Creo que se procesa principalmente en el lado del cliente, y todo el cliente necesita el hash de confirmación en la red.

Ron
fuente
¿Qué escenario estás describiendo? El caso en el que hice xy ye necesidad de tirar ey ddesde el servidor? El problema inicial es que yo (como cliente) no conozco el "punto de ramificación" c.
Martin Geisler