Cerca binario o Btree problema aggiornamento dell'indice

voti
4

Immaginate che si è consegnato un nuovo libro di tutti i giorni da un autore. Il libro è un work in progress. Egli non dice quello che è cambiato o aggiunto.

Il vostro compito è quello di identificare le modifiche e integrazioni, e passare solo questi insieme alla casa editrice (che non ha tempo di leggere l'intero libro di tutti i giorni)

Ai fini di questo problema, il libro è composto da 1m righe di testo ASCII e in crescita (in realtà un file di backup di MySQL).

La mia idea attuale è quella di fare un hash sicuro (SHA256 per esempio) di ogni riga (1k caratteri) e riporlo su HD. Dal momento che l'hash è solo 32bytes il file è solo 32 MB.

Poi, quando si ottiene il file successivo di domani, passiamo attraverso riga per riga, creando un nuovo hash per ogni linea e confrontandola con l'hash del giorno precedente.

Quando il processo è terminato abbiamo sovrascrivere il file hash pronto per il giorno successivo.

Il confronto utilizza un metodo di ricerca binaria di stringa di confronto (> <operandi) Questa restituisce un risultato in una media di quattro iterazioni.

Non ho ancora codificato una soluzione indice di btree, ma come è possibile affrontare questo?

È pubblicato 30/10/2008 alle 01:52
fonte dall'utente
In altre lingue...                            


6 risposte

voti
1

Vorrei usare diff .

Se avevo bisogno per la sua attuazione entro il mio programma, vorrei utilizzare uno degli algoritmi per la ricerca della più lunga sottosequenza comune di due sequenze, trattando ogni file come una sequenza di linee.

Risposto il 30/10/2008 a 01:58
fonte dall'utente

voti
0

"Poi, quando si ottiene il file successivo di domani, andiamo attraverso la linea che per linea, creando un nuovo hash per ogni linea e confrontandola con l'hash del giorno precedente."

Capito: linee 1m di valori hash di oggi rispetto a 1m linee di valori di ieri.

Do linee vengono inseriti o rimossi? In caso contrario, si tratta di un semplice insieme di parallele si legge, per vedere se gli hash sono diverse.

Se ci sono, aggiunge o rimozioni, si dovrà utilizzare l'algoritmo diff per determinare la portata del cambiamento.

Tutto va bene. Non troppo difficile da attuare.

In tale contesto, il seguente non ha senso.

Il confronto utilizza un metodo di ricerca binaria di stringa di confronto (> <operandi) Questa restituisce un risultato in una media di quattro iterazioni.

C'è una sorta di ordinare ai valori di hash? O qualche struttura ad albero?

Risposto il 30/10/2008 a 02:20
fonte dall'utente

voti
0

Un libro di 1 milione di linee è enorme: ci sono forse 30 - 50 righe per pagina, quindi cerchiamo di essere generosi e assumono 100 righe per pagina, il che significa che 10.000 pagine del libro.

Linee di 1 KB sono anche molto più grandi è normale; leggibilità base suggerisce neanche lontanamente che molti caratteri per riga. Avete intenzione di hash linee fino a 1 KB, o pezzo il file in 1 KB pezzi? Un problema con il vostro schema è che le linee ripetute avrebbero un hash ripetuto; non si potrebbe mai identificare quando una di queste linee è stato aggiunto o eliminato.

Si potrebbe, presumibilmente, hanno bisogno di informare l'editore di linee eliminate troppo.

Come con Glomek, vorrei utilizzare diffsul file. Se si mantiene il file con RCS o CVS di controllo, si avrebbe solo versione attuale del file e le diff tra le versioni precedenti memorizzati. Con questo, si sarebbe in grado di fornire diff cumulativi più di una settimana o un mese troppo.

E probabilmente non sarei sviluppare il mio indicizzazione B-Tree.

Risposto il 30/10/2008 a 02:23
fonte dall'utente

voti
0

la soluzione che si descrive è in qualche modo simile all'algoritmo rsync. un punto importante è che rsync deve riconoscere pezzi esistenti in qualsiasi parte del file di destinazione, in qualsiasi offset originale.

se i file sono veramente RECORD-strutturati, è possibile semplificare un po 'come lei propone. se non, avete bisogno di un checksum di rotolamento.

Inoltre, si deve riconoscere reorderings? oppure solo inserzioni / delezioni / sostituzioni?

il caso più generica è l'algoritmo di rsync completo, che va in questo modo:

  • Definizione parametri:

    1. scegliere una dimensione del blocco 512, o 1k di solito lavorano ok.
      • scegliere un checksum 'forte'. qualcosa di simile da MD4 o giù di lì. 64bits sono un sacco.
      • scegliere un 'debole' checksum rotolamento. uno che ti permette di 'sottrarre' il byte coda e 'aggiungere' un byte testa per ottenere il checksum di un blocco 1 byte in avanti. di solito un checksum a 16 bit funziona bene.
  • firma del vecchio file:

    1. traverso l'intero file vecchio, ad ogni blocco calcolare checksum sia deboli e forti. con 16 e 64 bit checksum e blocchi 512byte che significa 10bytes per blocco, o 20KB per megabyte. questa è la 'firma'
  • creare 'patch' con nuovo file, e firma del vecchio file:

    1. caricare la firma del vecchio file, la cosa migliore è una tabella hash, checksum con i deboli come le chiavi, i checksum forti e la posizione di blocco sono i valori.
      • leggere il primo blocco del nuovo file
      • calcolare il checksum debole di blocco loaded
      • controllare la tabella di hash per verificare se il checksum debole è lì.
      • se trovato, calcolare il forte checksum e confrontare con quello trovato nella hash
      • se entrambi i checksum corrispondono, come segno di 'ottenuto' con il riferimento di blocco nella hash, avanzare di un intero del blocco e tornare al punto 3
      • se il forte checksum non corrisponde, o se il checksum debole non era in hash, 'roll' la somma di controllo deboli, cioè, 'aggiungere' il byte successivo dopo il blocco, e 'sottrarre' il primo byte dal coda.
      • aggiungi il byte 'sottratto' dalla coda all'elenco dei 'nuovi' byte nella patch
      • tornare al passo 4
  • applicare la patch al vecchio file

    1. il 'patch' è l'elenco dei 'nuovi' byte che cadevano fuori durante il rotolamento del checksum, più la lista dei 'capito' blocchi che partita sul vecchio file.
Risposto il 30/10/2008 a 02:34
fonte dall'utente

voti
0

Questa è una tecnica utilizzata per il caricamento incrementale su un data warehouse. Nella situazione in cui non si ha la capacità di identificare dati modificati all'interno di un sistema di origine, si può prendere uno snapshot dei dati e confrontarlo con il tuo ultimo snapshot per identificare le differenze. Questa tecnica ottiene anche una menzione nel libro di Ralph Kimball su questo argomento ed è usato in un'applicazione Sono stato coinvolto nella progettazione di.

Avete bisogno di un algoritmo di hashing con una vasta chiave come questo approccio è vulnerabile agli attacchi di compleanno . MD5 o SHA della famiglia sarebbe bene. Inoltre, non può rilevare le eliminazioni senza un post-processo che passa attraverso la differenza alla ricerca di dispersi chiavi naturali. Questo calcolo effettivamente deve essere a conoscenza della struttura della tabella.

Risposto il 30/10/2008 a 09:44
fonte dall'utente

voti
0

Un problema con il vostro schema è che le linee ripetute avrebbero un hash ripetuto; non si potrebbe mai identificare quando una di queste linee è stato aggiunto o eliminato

Molto buon punto, ma non è un problema. Una linea ripetuta è un duplicato e tutti i duplicati vengono eliminati nella prossima fase di lavorazione. Quindi sì hai ragione, ma non è un problema.

Link "diff" mi porta a una pagina con la descrizione di quello che presumo è un'applicazione? Non v'è alcun link per il download, non esiste un codice in qualsiasi lingua ... Che cosa manco qui?

Alcuni di voi hanno parlato di livello di byte granularità. Questo non è necessario. è richiesto solo granularità a livello di linea, perché se qualcosa sulla linea è stata modificata, l'intera linea (record) deve essere ritrattato becasue ogni cambiamento all'interno della linea colpisce l'intera linea.

Quindi stiamo confrontando linee di circa 1000 caratteri (senza binari), in due file (oggi snapshot e snapshot di ieri) che sono ciascuno circa linee 1m.

Quindi, utilizzando un hash sicuro come SHA256 (MD5 ha collisioni ed è lento in confronto) posso processare circa 30MB / sec sul mio portatile HO. Il server naturalmente masticare attraverso di essa molto più veloce.

Quindi, se il file è arond 1GB, poi fare tutte le hases dura circa 33sec, e la lettura di file da 1 Gb di memoria utilizzando Windows pagina richiede circa 30 secondi. non orribile

Ora abbiamo due array di hashs che rappresentano le linee in ogni file. Se li ordiniamo, ora possiamo usare una ricerca binaria, così abbiamo iterare il nostro modo attraverso i nuovi file hashs alla ricerca di una corrispondenza nei file vecchi hashs. Se noi non trovarlo, si aggiunge che la linea al file modifiche.

Tenete a mente che il libro di linee (database legacy) è sconosciuta in ogni aspetto. Non v'è alcuna garanzia di ordine delle linee, la posizione di cambiamenti, tipo di modifiche.

I suggerimenti di lettura pagina per pagina foreward è buono, ma si presume che i due file sono nell'ordine smae up fino alla prima modifica. Questo non può essere assunto. Le linee (righe) potrebbe essere in qualsiasi ordine. scegliendo anche una dimensione del blocco arbitrario viola la granularità di una linea. Ai fini di questa operazione, le linee sono immutabili.

Da quel eccellente collegamento sul invrementa carico: file di confronto Capture: Questo metodo è noto anche come il metodo snapshot differenziale. Questo metodo funziona mantenendo prima e dopo le immagini di file che sono fonte di preoccupazione per il data warehouse. I record sono confrontati per trovare i cambiamenti, e le chiavi di registrazione vengono confrontate per trovare inserti ed eliminazioni. Questa tecnica è più appropriato nel caso di sistemi legacy a causa del fatto che si innesca in genere non esistono e registri delle transazioni sono o inesistenti o in un formato proprietario. Poiché la maggior parte dei database legacy hanno un qualche meccanismo per il dumping dei dati in file, questa tecnica crea istantanee periodiche e quindi confronta i risultati per la produzione record di modifica. Certo, tutti i problemi di cattura statica sono qui presenti. complessità è introdotto dalla sfida di confrontare intere righe di informazioni e di identificazione chiave e di corrispondenza. Questa tecnica è di natura complessa e tipicamente non desiderabile, ma, in alcuni casi, può essere l'unica soluzione.

Questo è più rilevante qui: Come si procede nel regno di data warehouse terabyte, la possibilità di ricostruire il data warehouse da zero su base giornaliera farà la fine dei dinosauri. L'approccio logico ed efficiente per l'aggiornamento del data warehouse comporta qualche forma di strategia di aggiornamento incrementale.

Quindi credo che io sono sulla strada giusta, allora? Un indice btree non offrirebbe un vantaggio?

Risposto il 31/10/2008 a 08:47
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more