Confronto DAG efficiente su una rete


11

Nei sistemi di controllo di versione distribuito (come Mercurial e Git ) è necessario confrontare in modo efficiente i grafici aciclici diretti (DAG). Sono uno sviluppatore Mercurial e saremmo molto interessati a conoscere il lavoro teorico che discute della complessità temporale e di rete del confronto tra due DAG.

I DAG in questione sono formati dalle revisioni registrate. Le revisioni sono identificate in modo univoco da un valore hash. Ogni revisione dipende da zero (commit iniziale), uno (commit normale) o più (commit di unione) delle revisioni precedenti. Ecco un esempio in cui le revisioni aper estati fatti uno dopo l'altro:

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

Il confronto dei grafici viene visualizzato quando qualcuno ha solo una parte della cronologia e desidera recuperare la parte mancante. Immaginate Ho dovuto aalla ce feci xe ybasandomi su c:

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

In Mercurial, farei hg pulle scaricare de e:

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

L'obiettivo è quello di identificare de ein modo efficiente quando il grafico ha molti (diciamo, più di 100.000) nodi. L'efficienza riguarda entrambi

  • complessità della rete: il numero di byte trasferiti e il numero di round trip della rete necessari
  • complessità temporale: la quantità di calcolo effettuata dai due server che scambiano i changeset

I grafici tipici saranno stretti con poche tracce parallele come sopra. Di solito ci saranno solo una manciata di nodi foglia (li chiamiamo teste in Mercurial) come ee ysopra. Infine, quando viene utilizzato un server centrale, il client avrà spesso un paio di changeset che non si trovano sul server, mentre il server può avere oltre 100 nuovi changeset per i client, a seconda di chi molto tempo fa il client ha estratto l'ultima volta dal server . È preferibile una soluzione asimmetrica : un server centralizzato dovrebbe fare pochi calcoli rispetto ai suoi client.


La discussione è proseguita un po ' su Google Plus .
Martin Geisler,

Risposte:


13

In questo contesto, i nodi del grafico hanno una sorta di identificatore univoco (un hash o checksum), giusto? Quindi non è necessario eseguire alcun tipo di test dell'isomorfismo dei sottografi, è sufficiente un elenco dei nodi che differiscono tra le due versioni e i bordi non sono affatto utili per questo passaggio. Il mio documento SIGCOMM 2011 " Qual è la differenza? Riconciliazione efficiente dei set senza contesto precedente"(con Goodrich, Uyeda e Varghese) considera esattamente questo problema: si scopre che è possibile determinare le identità dei nodi che sono detenute da uno ma non da entrambi i due server comunicanti, usando una quantità di comunicazione che è solo proporzionale al numero di nodi modificati e utilizzando solo un solo round-trip. Una volta ottenute tali informazioni, è facile estrarre le modifiche stesse in un secondo round-trip, sempre con una comunicazione ottimale.


Sembra interessante! Hai ragione sul fatto che un confronto diretto degli ID del changeset (sì, sono valori di hash) funzionerà. Abbiamo sempre cercato di usare anche la struttura del grafico: se entrambi conosciamo X, so anche che conosci tutti gli antenati di X. Sembra un'informazione importante, ma forse non lo è. Leggerò il tuo documento ora, grazie per il puntatore!
Martin Geisler,

@ David: una precisione (sono uno degli autori dell'algoritmo attualmente utilizzato da Mercurial). In realtà ci preoccupiamo dell'insieme di nodi "comuni", non è necessario conoscere il valore del nodo mancante.
tonfa,

1
Se sai cosa è diverso, allora sai anche cosa c'è in comune: è tutto ciò che hai una copia che non fa parte della differenza. Ma la differenza dovrebbe essere in genere relativamente piccola anche quando la parte comune è grande, quindi comunicare solo una quantità di dati proporzionale alla differenza è meglio che comunicare l'intero DAG storico o la parte comune.
David Eppstein,

@David: a causa della relazione degli antenati, in realtà calcoliamo le teste (nodi foglia) della regione comune. Quindi questa è ancora una piccola quantità di dati, anche se c'è un'enorme storia condivisa.
Martin Geisler,

Ho aggiornato la mia risposta per includere anche il numero di viaggi di andata e ritorno utilizzati (che risulta essere molto ridotto).
David Eppstein,

3

Nella soluzione che abbiamo implementato per Mercurial, un'altra preoccupazione era l'asimmetria: il carico del server dovrebbe essere ridotto al minimo sia per la larghezza di banda in uscita che per il tempo della CPU, a costo del carico del client.


1
Grazie, ho aggiornato un po 'la domanda per notare questo.
Martin Geisler,

0

Mi sembra un processo in due fasi.

  1. chiedi a tutti i clienti se hanno commesso dove si trova il genitore c
  2. in tal caso, trova tutti i bambini di c

Il compito di 1. Penso che sia principalmente elaborato dal lato client e tutto il client ha bisogno dell'hash di commit sulla rete.


Quale scenario stai descrivendo? Il caso in cui ho realizzato xe yed è necessario estrarre ee ddal server? Il problema iniziale è che io (come cliente) non conosco il "punto di diramazione" c.
Martin Geisler,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.