SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
Filtri di Bloom


               Davide Carboni
      Corso di Computazione su Rete
Laurea specialistica in Tecnologie Informatiche
         Facoltà Scienze MM.FF.NN
            Università di Cagliari
                AA 2007/2008
Bloom Filter
●   Un filtro di Bloom B è una struttura dati ottimizzata rispetto allo
    spazio utilizzata per testare se un dato elemento x ∈ S
●   Il filtro evita di cercare l'elemento x con un'iterazione
●   E' possibile che restituisca dei falsi positivi
●   Gli elementi che vengono aggiunti al set S devono essere
    aggiunti anche al filtro. Gli elementi rimossi da S non possono
    essere rimossi dal filtro
Bloom Filter
●   Un filtro di Bloom B è definito da un vettore di m
    bit e da k-funzioni di hashing per le quali vale
●   fi(x) = j con 0 <= j <= m per qualunque i=1,2,...,k
●   In pratica ogni funzione di hash calcola una
    posizione all'interno del vettore B
Bloom Filter: add
●   Quando un elemento y viene aggiunto al set S
    allora si calcolano tutte le funzioni di hash
    –   f1(y),f2(y),...,fk(y)
●   e il vettore risultante contiene k-posizioni del
    filtro di Bloom che devono essere posti a uno
●   B[fi(y)] := 1 per i=1,2,...,k
Bloom Filter: query
●   Per testare se un elemento y ∈ S è sufficiente
    calcolare f1(y),f2(y),...,fk(y) e verificare che
●   B[fi(y)] == 1 per i=1,2,...,k
●   Se uno solo dei B[fi(y)] == 0 allora l'elemento
    y non è in S
Falsi positivi
●   In generale quando aggiungiamo un elemento x
    calcoliamo il vettore di posizioni da settare
●   B[fi(x)] := 1 per i=1,2,...,k
●   Se aggiungiamo anche y avremo
●   B[fi(y)] := 1 per i=1,2,...,k
●   In generale potrà accadere che fi(x) == fj(y) per
    x e y presi in modo arbitrario
Falsi positivi
●   In generale potrà accadere che fi(x) == fj(y) per
    x e y presi in modo arbitrario
●   Questo conduce al fatto che dati più elementi
    x1,x2,...,xp possono dar luogo al settaggio di
    B[i1],B[i2],...,B[ik] tale per cui un generico
    elemento y avente esattamente B[i1],B[i2],...,B[ik]
    come impronta risulterebbe positivo pur non
    essendo nel set S
Falso positivo esempio

   00100000100000000000000000001     add 'mela'




   00100000100100100000010000001     add 'pera'



   00101000100100100110010000001     add 'kiwi'




   00000000000100000100000000001     test 'arancia'


test(arancia) da un falso positivo
Falsi positivi: calcolo
●   Supponiamo che la probabilità che un dato bit
    del filtro sia settato a 1 da una funzione di hash
    sia 1/m, dunque la prob. che NON sia settato a
    1 sarà 1– 1/m
●   La prob. che non sia settato da nessuna delle
    k-funzioni sarà (1 – 1/m)k
●   La prob. che sia ancora zero dopo aver inserito
    n elementi sarà (1 – 1/m)kn
Falsi positivi: calcolo
●   La prob. che sia pari ad uno dopo aver inserito
    n elementi sarà 1 - (1 – 1/m)kn
●   Dato un elemento e che non appartiene a S la
    prob. che tutti i k-bit della sua impronta sul filtro
    siano settati ad uno è quindi
●   (1 - (1 – 1/m)kn)k ≃ (1 – e -kn/m)k
Casi d'uso
●   spell-checker: un filtro di Bloom accetta tutte le parole
    in un dato dizionario e non le altre
●   p2p: una query che è stata già inviata senza successo
    in un ramo della rete non verrà ri-inviata
●   spam: per verificare che l'indirizzo di uno spammer sia
    in una black list
●   Google BigTable usa i filtri di Bloom per evitare le
    ricerche in colonne vuote
Cache distribuite
                   proxy

                               cache




client     1       proxy
         get x                                  internet
                               cache



             proxy

                           cache


proxy                                  il client interroga il proxy
                                       per ottenere l'oggetto x
           cache
Cache distribuite
                   proxy

                                 cache




                                x in cache?
client    1        proxy    2
         get x                   cache                       internet



              proxy

                           cache

                                              il proxy interroga la sua cache
proxy                                         x in cache?
           cache
Cache distribuite
                     proxy

                                  cache



                         3
                                 x in cache?
client       1       proxy   2
         get x                    cache                   internet
                    3
         3




                 proxy

                             cache
                                               il proxy non trovando x nella sua cache
                                               inoltra la richiesta alle altre cache da
proxy
                                               lui conosciute ognuna delle quali dovra
             cache                             interrogare x in cache?
Cache distribuite
                     proxy

                                  cache



                         3
                                 x in cache?
client       1       proxy   2
         get x                                 4          internet
                                  cache
                    3
         3




                 proxy

                             cache
                                               il proxy non trovando x in nessuna
                                               cache si collegherà con la vera risorsa
proxy
                                               x in rete
             cache
Cache distribuite (con Bloom)
                   proxy

                                   cache


                                   bloom filters

client     1       proxy
         get x                                                       internet
                           cache


             proxy

                            cache


proxy                                              il client interroga il proxy
                                                   per ottenere l'oggetto x
           cache
Cache distribuite (con Bloom)
                   proxy

                                   cache


                                   bloom filters

client     1       proxy
         get x                                                             internet
                           cache


             proxy

                            cache
                                            il proxy interroga il filtro relativo alla
                                            sua cache
proxy

           cache
Cache distribuite (con Bloom)
                   proxy

                                   cache


                                   bloom filters

client     1       proxy
         get x                                                                internet
                           cache


             proxy

                            cache

                                                   se x not in cache allora il proxy
proxy                                              farà la query sugli altri filtri relativi
                                                   alle cache remote
           cache
Cache distribuite (con Bloom)
                   proxy

                                   cache


                                   bloom filters

client     1       proxy
         get x                                                            internet
                           cache


             proxy

                            cache

                                                   se nessun filtro restituisce query(x) = true
proxy                                              allora la risorsa viene caricata dalla rete
           cache
Cache distribuite (considerazioni)
●   Senza filtri di Bloom la query x in cache?
    richiede un calcolo O(log n) al quale nel caso
    peggiore di consultazione di k cache remote va
    a sommarsi il tempo di latenza Tl (che
    consideriamo qui come media) per ognuna
    delle consultazioni
●   Con i filtri di Bloom non c'è latenza di rete ed
    inoltre la consultazione per la singola filtro è
    molto più breve di O(log n)
Cache distribuite (considerazioni)
●   In caso un filtro restituisca x in filter=true
    –   se x in cache (vero positivo) OK, è quello che
        volevamo
    –   se x not in cache (falso positivo): allora il proxy
        chiederà inutilmente get x ad una cache ottenendo
        un Error 404
Cancellare un elemento
●   Cancellare un elemento da un filtro di Bloom
    non è possibile senza ricostruire il filtro
●



        00100000100000000000000000001                          add 'mela'




                                                                add 'uva'
        00100010000000000000000001000


            delete 'uva' distruggerebbe anche l'impronta di 'mela'
Cancellare un elemento
●   Si potrebbero usare per un set S={x1,...,xn} due
    filtri di bloom A,D
    –   A è il filtro di Bloom che contiene tutti gli elementi
        aggiunti (added)
    –   D è il filtro di Bloom che contiene tutti gli elementi
        cancellati (deleted)
    –   la query x in S? va verificata con le due query sui
        filtri x in A? and x not in D?
Counting Filters
●   Un modo più interessante per consentire la
    cancellazione è quello di costruire degli speciali
    filtri in cui invece di settare a 1 i bit si
    incrementano dei contatori
●   In effetti il filtro di Bloom può essere considerato
    un Counting Filter in cui i contatori stanno
    nell'intervallo [0,1]
Counting Filters
●   00000000000000000 (filtro vuoto)
●   00001000000010010 (add x)
●   00002000100110010 (add y)
●   00002001200110010 (add z)
●   00001001200100000 (delete x)
Filtri Bloomier
●   I filtri Bloomier sono una struttura dati basata
    sui filtri di Bloom capace di implementare un
    array associativo
●   Dato l'array A:
    –   add (key,value) equivalente a A[key] = value
    –   value=get(key) equivalente a value = A[key]
Filtri Bloomier
●   Il caso più semplice è quello in cui i valori
    dell'array possono assumere i valori 1 e 0
    –   value ∊ {0,1}
●   Si utilizzano due filtri di Bloom A e B
    –   A contiene tutte le chiavi i cui valori sono 0
    –   B contiene tutti le chiavi i cui valori sono 1
Bloomier (Esempi)
●   A=00000000000000000 (array vuoto)
●   B=00000000000000000
●   A=00000000000000000                   array[x]=1
●   B=00010000101000000
         h (x) h (x) h (x)
              1           2   3




●   A=01000100000000100                   array[y]=0
●   B=00010000101000000
      h1(y)       h2(y)           h3(y)
Bloomier (Esempi)
●   Facciamo l'ipotesi che non modifichiamo mai il
    valore associato ad una chiave
    –   se imponiamo array[x] := 0 non imporremo in
        seguito array[x] := 1
    –   pertanto se risulta contemporaneamente che
         ●   array[x] == 1 and array[x] == 0 questo è dovuto al fatto
             che uno o tutt'e due i filtri di Bloom A e B stanno
             restituendo un falso positivo
Bloomier non binari
●   Il caso più generale è quello in cui i valori dell'array
    possono assumere valori qualsiasi.
●   Essi possono rappresentare un puntatore a n bit ad una
    qualche zona di memoria
     –   value ∊ [00...0n , 11...1n]
●   Si utilizzano 2*n filtri di Bloom A1,...,An e B1,...,Bn
     –   x in Ai => i-esimo bit di array[x] == 0
     –   x in Bi => i-esimo bit di array[x] == 1
Bloomier non binari (Esempi)
●    A1 = 000000000000
●    A2 = 000000000000
●    B1 = 000000000000
●    B2 = 000000000000

    consideriamo un filtro in cui i valori
    array[x] appartengano a {00,01,10,11}
Bloomier non binari (Esempi)
●   A1 = 001000010010
●   A2 = 000000000000
●   B1 = 000000000000
●   B2 = 001000010010


settiamo array[x] := 01
                          indici per x
Bloomier non binari (Esempi)
●   A1 = 001000010010
●   A2 = 000000000000
●   B1 = 100010000001
●   B2 = 101010010011


settiamo array[y] := 11
                          indici per y
Riferimenti
●   Bloom, Burton H. (1970),
     –   "Space/time trade-offs in hash coding with
         allowable errors",
●   Chazelle e altri (2004),
     –   "The Bloomier filter: an efficient data structure for
         static support lookup tables"
●   Talk on Bloom Filter by GoogleTechTalks
    http://www.youtube.com/watch?v=947gWqwkhu0

Mais conteúdo relacionado

Mais de Davide Carboni

Internet of Things al Festivalscienza 2010
Internet of Things al Festivalscienza 2010Internet of Things al Festivalscienza 2010
Internet of Things al Festivalscienza 2010Davide Carboni
 
Introduzione ai Design Patterns nella Programmazione a Oggetti
Introduzione ai Design Patterns nella Programmazione a OggettiIntroduzione ai Design Patterns nella Programmazione a Oggetti
Introduzione ai Design Patterns nella Programmazione a OggettiDavide Carboni
 
The world is the computer and the programmer is you
The world is the computer and the programmer is youThe world is the computer and the programmer is you
The world is the computer and the programmer is youDavide Carboni
 
Browsing Large Collections of Geo-Tagged Pictures
Browsing Large Collections of Geo-Tagged PicturesBrowsing Large Collections of Geo-Tagged Pictures
Browsing Large Collections of Geo-Tagged PicturesDavide Carboni
 
Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Davide Carboni
 
Kickoff del Progetto Cluster Mashup e Geoweb
Kickoff del Progetto Cluster Mashup e GeowebKickoff del Progetto Cluster Mashup e Geoweb
Kickoff del Progetto Cluster Mashup e GeowebDavide Carboni
 
Open al bivio fra software e webware (al javaday 2006)
Open al bivio fra software e webware (al javaday 2006)Open al bivio fra software e webware (al javaday 2006)
Open al bivio fra software e webware (al javaday 2006)Davide Carboni
 
Web 2.0, mashup e GeoWeb
Web 2.0, mashup e GeoWebWeb 2.0, mashup e GeoWeb
Web 2.0, mashup e GeoWebDavide Carboni
 
Open al bivio fra software e webware
Open al bivio fra software e webwareOpen al bivio fra software e webware
Open al bivio fra software e webwareDavide Carboni
 

Mais de Davide Carboni (13)

2 phase-commit
 2 phase-commit 2 phase-commit
2 phase-commit
 
Internet of Things al Festivalscienza 2010
Internet of Things al Festivalscienza 2010Internet of Things al Festivalscienza 2010
Internet of Things al Festivalscienza 2010
 
Introduzione ai Design Patterns nella Programmazione a Oggetti
Introduzione ai Design Patterns nella Programmazione a OggettiIntroduzione ai Design Patterns nella Programmazione a Oggetti
Introduzione ai Design Patterns nella Programmazione a Oggetti
 
The world is the computer and the programmer is you
The world is the computer and the programmer is youThe world is the computer and the programmer is you
The world is the computer and the programmer is you
 
Browsing Large Collections of Geo-Tagged Pictures
Browsing Large Collections of Geo-Tagged PicturesBrowsing Large Collections of Geo-Tagged Pictures
Browsing Large Collections of Geo-Tagged Pictures
 
Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)
 
NAT Traversal
NAT TraversalNAT Traversal
NAT Traversal
 
Introduction P2p
Introduction P2pIntroduction P2p
Introduction P2p
 
Spoleto07
Spoleto07Spoleto07
Spoleto07
 
Kickoff del Progetto Cluster Mashup e Geoweb
Kickoff del Progetto Cluster Mashup e GeowebKickoff del Progetto Cluster Mashup e Geoweb
Kickoff del Progetto Cluster Mashup e Geoweb
 
Open al bivio fra software e webware (al javaday 2006)
Open al bivio fra software e webware (al javaday 2006)Open al bivio fra software e webware (al javaday 2006)
Open al bivio fra software e webware (al javaday 2006)
 
Web 2.0, mashup e GeoWeb
Web 2.0, mashup e GeoWebWeb 2.0, mashup e GeoWeb
Web 2.0, mashup e GeoWeb
 
Open al bivio fra software e webware
Open al bivio fra software e webwareOpen al bivio fra software e webware
Open al bivio fra software e webware
 

04 bloom

  • 1. Filtri di Bloom Davide Carboni Corso di Computazione su Rete Laurea specialistica in Tecnologie Informatiche Facoltà Scienze MM.FF.NN Università di Cagliari AA 2007/2008
  • 2. Bloom Filter ● Un filtro di Bloom B è una struttura dati ottimizzata rispetto allo spazio utilizzata per testare se un dato elemento x ∈ S ● Il filtro evita di cercare l'elemento x con un'iterazione ● E' possibile che restituisca dei falsi positivi ● Gli elementi che vengono aggiunti al set S devono essere aggiunti anche al filtro. Gli elementi rimossi da S non possono essere rimossi dal filtro
  • 3. Bloom Filter ● Un filtro di Bloom B è definito da un vettore di m bit e da k-funzioni di hashing per le quali vale ● fi(x) = j con 0 <= j <= m per qualunque i=1,2,...,k ● In pratica ogni funzione di hash calcola una posizione all'interno del vettore B
  • 4. Bloom Filter: add ● Quando un elemento y viene aggiunto al set S allora si calcolano tutte le funzioni di hash – f1(y),f2(y),...,fk(y) ● e il vettore risultante contiene k-posizioni del filtro di Bloom che devono essere posti a uno ● B[fi(y)] := 1 per i=1,2,...,k
  • 5. Bloom Filter: query ● Per testare se un elemento y ∈ S è sufficiente calcolare f1(y),f2(y),...,fk(y) e verificare che ● B[fi(y)] == 1 per i=1,2,...,k ● Se uno solo dei B[fi(y)] == 0 allora l'elemento y non è in S
  • 6. Falsi positivi ● In generale quando aggiungiamo un elemento x calcoliamo il vettore di posizioni da settare ● B[fi(x)] := 1 per i=1,2,...,k ● Se aggiungiamo anche y avremo ● B[fi(y)] := 1 per i=1,2,...,k ● In generale potrà accadere che fi(x) == fj(y) per x e y presi in modo arbitrario
  • 7. Falsi positivi ● In generale potrà accadere che fi(x) == fj(y) per x e y presi in modo arbitrario ● Questo conduce al fatto che dati più elementi x1,x2,...,xp possono dar luogo al settaggio di B[i1],B[i2],...,B[ik] tale per cui un generico elemento y avente esattamente B[i1],B[i2],...,B[ik] come impronta risulterebbe positivo pur non essendo nel set S
  • 8. Falso positivo esempio 00100000100000000000000000001 add 'mela' 00100000100100100000010000001 add 'pera' 00101000100100100110010000001 add 'kiwi' 00000000000100000100000000001 test 'arancia' test(arancia) da un falso positivo
  • 9. Falsi positivi: calcolo ● Supponiamo che la probabilità che un dato bit del filtro sia settato a 1 da una funzione di hash sia 1/m, dunque la prob. che NON sia settato a 1 sarà 1– 1/m ● La prob. che non sia settato da nessuna delle k-funzioni sarà (1 – 1/m)k ● La prob. che sia ancora zero dopo aver inserito n elementi sarà (1 – 1/m)kn
  • 10. Falsi positivi: calcolo ● La prob. che sia pari ad uno dopo aver inserito n elementi sarà 1 - (1 – 1/m)kn ● Dato un elemento e che non appartiene a S la prob. che tutti i k-bit della sua impronta sul filtro siano settati ad uno è quindi ● (1 - (1 – 1/m)kn)k ≃ (1 – e -kn/m)k
  • 11. Casi d'uso ● spell-checker: un filtro di Bloom accetta tutte le parole in un dato dizionario e non le altre ● p2p: una query che è stata già inviata senza successo in un ramo della rete non verrà ri-inviata ● spam: per verificare che l'indirizzo di uno spammer sia in una black list ● Google BigTable usa i filtri di Bloom per evitare le ricerche in colonne vuote
  • 12. Cache distribuite proxy cache client 1 proxy get x internet cache proxy cache proxy il client interroga il proxy per ottenere l'oggetto x cache
  • 13. Cache distribuite proxy cache x in cache? client 1 proxy 2 get x cache internet proxy cache il proxy interroga la sua cache proxy x in cache? cache
  • 14. Cache distribuite proxy cache 3 x in cache? client 1 proxy 2 get x cache internet 3 3 proxy cache il proxy non trovando x nella sua cache inoltra la richiesta alle altre cache da proxy lui conosciute ognuna delle quali dovra cache interrogare x in cache?
  • 15. Cache distribuite proxy cache 3 x in cache? client 1 proxy 2 get x 4 internet cache 3 3 proxy cache il proxy non trovando x in nessuna cache si collegherà con la vera risorsa proxy x in rete cache
  • 16. Cache distribuite (con Bloom) proxy cache bloom filters client 1 proxy get x internet cache proxy cache proxy il client interroga il proxy per ottenere l'oggetto x cache
  • 17. Cache distribuite (con Bloom) proxy cache bloom filters client 1 proxy get x internet cache proxy cache il proxy interroga il filtro relativo alla sua cache proxy cache
  • 18. Cache distribuite (con Bloom) proxy cache bloom filters client 1 proxy get x internet cache proxy cache se x not in cache allora il proxy proxy farà la query sugli altri filtri relativi alle cache remote cache
  • 19. Cache distribuite (con Bloom) proxy cache bloom filters client 1 proxy get x internet cache proxy cache se nessun filtro restituisce query(x) = true proxy allora la risorsa viene caricata dalla rete cache
  • 20. Cache distribuite (considerazioni) ● Senza filtri di Bloom la query x in cache? richiede un calcolo O(log n) al quale nel caso peggiore di consultazione di k cache remote va a sommarsi il tempo di latenza Tl (che consideriamo qui come media) per ognuna delle consultazioni ● Con i filtri di Bloom non c'è latenza di rete ed inoltre la consultazione per la singola filtro è molto più breve di O(log n)
  • 21. Cache distribuite (considerazioni) ● In caso un filtro restituisca x in filter=true – se x in cache (vero positivo) OK, è quello che volevamo – se x not in cache (falso positivo): allora il proxy chiederà inutilmente get x ad una cache ottenendo un Error 404
  • 22. Cancellare un elemento ● Cancellare un elemento da un filtro di Bloom non è possibile senza ricostruire il filtro ● 00100000100000000000000000001 add 'mela' add 'uva' 00100010000000000000000001000 delete 'uva' distruggerebbe anche l'impronta di 'mela'
  • 23. Cancellare un elemento ● Si potrebbero usare per un set S={x1,...,xn} due filtri di bloom A,D – A è il filtro di Bloom che contiene tutti gli elementi aggiunti (added) – D è il filtro di Bloom che contiene tutti gli elementi cancellati (deleted) – la query x in S? va verificata con le due query sui filtri x in A? and x not in D?
  • 24. Counting Filters ● Un modo più interessante per consentire la cancellazione è quello di costruire degli speciali filtri in cui invece di settare a 1 i bit si incrementano dei contatori ● In effetti il filtro di Bloom può essere considerato un Counting Filter in cui i contatori stanno nell'intervallo [0,1]
  • 25. Counting Filters ● 00000000000000000 (filtro vuoto) ● 00001000000010010 (add x) ● 00002000100110010 (add y) ● 00002001200110010 (add z) ● 00001001200100000 (delete x)
  • 26. Filtri Bloomier ● I filtri Bloomier sono una struttura dati basata sui filtri di Bloom capace di implementare un array associativo ● Dato l'array A: – add (key,value) equivalente a A[key] = value – value=get(key) equivalente a value = A[key]
  • 27. Filtri Bloomier ● Il caso più semplice è quello in cui i valori dell'array possono assumere i valori 1 e 0 – value ∊ {0,1} ● Si utilizzano due filtri di Bloom A e B – A contiene tutte le chiavi i cui valori sono 0 – B contiene tutti le chiavi i cui valori sono 1
  • 28. Bloomier (Esempi) ● A=00000000000000000 (array vuoto) ● B=00000000000000000 ● A=00000000000000000 array[x]=1 ● B=00010000101000000 h (x) h (x) h (x) 1 2 3 ● A=01000100000000100 array[y]=0 ● B=00010000101000000 h1(y) h2(y) h3(y)
  • 29. Bloomier (Esempi) ● Facciamo l'ipotesi che non modifichiamo mai il valore associato ad una chiave – se imponiamo array[x] := 0 non imporremo in seguito array[x] := 1 – pertanto se risulta contemporaneamente che ● array[x] == 1 and array[x] == 0 questo è dovuto al fatto che uno o tutt'e due i filtri di Bloom A e B stanno restituendo un falso positivo
  • 30. Bloomier non binari ● Il caso più generale è quello in cui i valori dell'array possono assumere valori qualsiasi. ● Essi possono rappresentare un puntatore a n bit ad una qualche zona di memoria – value ∊ [00...0n , 11...1n] ● Si utilizzano 2*n filtri di Bloom A1,...,An e B1,...,Bn – x in Ai => i-esimo bit di array[x] == 0 – x in Bi => i-esimo bit di array[x] == 1
  • 31. Bloomier non binari (Esempi) ● A1 = 000000000000 ● A2 = 000000000000 ● B1 = 000000000000 ● B2 = 000000000000 consideriamo un filtro in cui i valori array[x] appartengano a {00,01,10,11}
  • 32. Bloomier non binari (Esempi) ● A1 = 001000010010 ● A2 = 000000000000 ● B1 = 000000000000 ● B2 = 001000010010 settiamo array[x] := 01 indici per x
  • 33. Bloomier non binari (Esempi) ● A1 = 001000010010 ● A2 = 000000000000 ● B1 = 100010000001 ● B2 = 101010010011 settiamo array[y] := 11 indici per y
  • 34. Riferimenti ● Bloom, Burton H. (1970), – "Space/time trade-offs in hash coding with allowable errors", ● Chazelle e altri (2004), – "The Bloomier filter: an efficient data structure for static support lookup tables" ● Talk on Bloom Filter by GoogleTechTalks http://www.youtube.com/watch?v=947gWqwkhu0