== La classe Map == Rappresenta una mappa di oggetti generici (''dataclass'') con uno spazio di levels x gsize. Cioè 4 x 256. Ricorda che il livello 0 contiene l'id dei singoli nodi, mentre il livello 3 contiene l'id dei gnodi più vasti. Il livello 4 non si specifica, consisterebbe in un unico gnodo che contiene l'intero dominio di IPv4. Ogni spazio viene creato usando il costruttore dataclass con i parametri lvl e id, così che l'oggetto che rappresenta un nodo nella mappa può avere l'informazione di dove si trova nella mappa (al momento la [[../ClasseRouteNode|classe RouteNode]] non ne fa uso).<
> La ''dataclass'' deve avere il metodo {{{is_free}}} per dire se lo spazio in questione è usato o no.<
> E' possibile segnalare la presenza di un nuovo nodo nella mappa. Si fa con il metodo {{{node_add}}}. In questo momento viene emesso il signal {{{NODE_NEW}}}.<
> E' possibile anche rimuovere un elemento dalla mappa. Si fa con il metodo {{{node_del}}}. In questo caso viene anche emesso il signal {{{NODE_DELETED}}}.<
> E' possibile anche resettare un intero livello o l'intera mappa senza far emettere alcun segnale ({{{map_reset}}}, {{{level_reset}}}). Questa tecnica è usata dopo aver fatto un re-hook in un diverso gnodo e aver reimpostato il nuovo IP su tutti i Nic attivi (vedi la [[../ClasseHook|classe Hook]]). Inoltre la classe Map tiene traccia del numero di nodi presenti di ogni livello, cioè il numero di spazi per cui {{{is_free() = False}}}. Lo memorizza nel membro {{{node_nb[lvl]}}}. <
> Oltre ad avere questo numero immediatamente pronto nel membro {{{node_nb[lvl]}}}, e come controparte il numero di nodi liberi calcolati come differenza nel metodo {{{free_nodes_nb(lvl)}}}, la classe fornisce anche il metodo {{{free_nodes_list(lvl)}}} che restituisce l'elenco degli {{{id}}} dei nodi liberi di livello {{{lvl}}}. <
> Importante: questi dati tengono conto anche del fatto che in IPv4 alcuni indirizzi non sono validi, tipo 192.168.* o 224.* etc. Nella classe Map l'attributo {{{me}}} memorizza il proprio spazio, cioè il proprio Netsukuku-IP (abbreviato {{{nip}}}). <
> Un nip è indicato nella forma di una sequenza di ID per i vari livelli dallo 0 al più alto. <
> {{{ self.me = [1,1,168,192]}}} <
> Notare che il primo elemento della sequenza è il livello 0 (l'id del singolo nodo) <
> Un altro modo di rappresentare uno spazio nella mappa è un intero, detto semplicemente {{{ip}}}, dato dal calcolo 192*256^3^+168*256^2^+1*256^1^+1*256^0^. <
> Per convertire tra le 2 notazioni si possono usare i metodi {{{ip_to_nip}}} e {{{nip_to_ip}}}. Per descrivere le altre funzionalità, supponiamo di avere a disposizione un altro indirizzo nella variabile {{{nip}}}. <
> {{{ nip = [2,2,168,192]}}} Il metodo {{{is_in_level}}} ci dice se un certo nodo o gnodo appartiene allo stesso nostro gnodo di livello x. In questo caso {{{self.is_in_level(nip,0)}}} darebbe {{{False}}};<
> invece {{{self.is_in_level(nip,1)}}} darebbe {{{True}}}. Il metodo {{{nip_cmp}}} dice di 2 Netsukuku-IP quale sia il primo livello differente. La ricerca parte dall'ultimo elemento delle sequenze (levels -1). Tra i 2 nip citati prima <
> {{{ nip_cmp(self.me, nip)}}} <
> dovrebbe restituire 1. Il metodo {{{lvlid_to_nip(lvl, id)}}} partendo da lvl e id guarda nella mappa e restituisce il nip equivalente. Lo fa partendo dal proprio nip (self.me) sostituendo il livello lvl con id e azzerando i livelli sotto lvl. === pack e merge === La classe {{{Map}}} fornisce un metodo '''map_data_pack''' che restituisce in una struttura tutti i dati della mappa (tranne le dimensioni {{{levels}}} e {{{gsize}}} che sono considerate note a priori). <
> Per la precisione si tratta di una tupla di 3 elementi: il proprio NIP, una copia della lista di liste di oggetti ''dataclass'', una copia della lista del numero di oggetti non liberi. <
> ''Notare'' che, per passare questa struttura ad un metodo remotable occorre che la classe usata come ''dataclass'' sia registrata come serializable con il [[../ModuloRencode|modulo rencode]]. Inoltre fornisce il metodo '''map_data_merge''' che usa come argomento una struttura dati dello stesso formato prodotto da {{{map_data_pack}}}. <
> Questo metodo verifica a quale livello sia il gnodo comune fra il suo attributo {{{me}}} e quello della mappa ricevuta. Lo fa con {{{nip_cmp}}} che ritorna il primo livello differente. I valori della mappa ricevuta il cui indice è maggiore o uguale a questo livello (ottenuto con {{{nip_cmp}}}) rappresentano gli stessi nodi per me e per il nodo della mappa ricevuta. Quelli inferiori rappresentano nodi diversi e non hanno significato per me. <
> Una volta stabilito quali valori della mappa ricevuta sono significativi per me, il metodo {{{map_data_merge}}} valorizza la mia mappa con i '''soli''' nodi della mappa ricevuta e resetta i livelli sottostanti. <
> In realtà il nome merge può essere fuorviante: non significa che i vecchi dati della propria mappa rimangono. Rimane solo il vecchio NIP e gli altri dati provenienti dall'altra mappa (di norma ricevuta da un nodo remoto) diventano significativi in quanto riferiti al nostro NIP. <
> E' usato nella classe {{{MapP2P}}}, derivata di {{{Map}}}, quando la classe {{{P2PAll}}} (vedi il [[../ModuloP2P|modulo P2P]]) recupera la mappa dei partecipanti da un suo nodo vicino attraverso il metodo remotable {{{pid_getall}}}. <
> Un'altra classe derivata di {{{Map}}}, la classe {{{MapCache}}} del [[../ModuloCoord|modulo coord]], dichiara remotable lo stesso metodo {{{map_data_merge}}} e la classe {{{Coord}}} lo usa per passare i dati da un Coordinator Node al suo successore.