It represents a map of generic objects (dataclass) in a space of levels * gsize. Cioè 4 * 256.
You should remember that level 0 contains id of single nodes, while level 3 contain id of largest gnodes. Level 4 is not specified, because it would be a single gnode which contains the entire domain of IPv4.
Each space is filled using constructor dataclass with parameters lvl and id, so that the object that represents a node in the map, can obtain the information about where it is inside the map (at the moment class RouteNode does not use it).
The dataclass must implement the method is_free to tell if the space is used or not.
It is possible to signal existence of a new node in the map. It can be done with method node_add. In that moment the signal NODE_NEW is emitted.
It is also possible to remove an element from the map. It can be done with method node_del. In that case is also emitted signal NODE_DELETED.
It is also possible to reset an entire level or the entire map without emitt any signal (map_reset, level_reset). This technic is used after doing a re-hook in a different gnode and having resetting the new IP on all active Nic (see class Hook).
Furthermore, class Map keeps track of the number of nodes contained in each level, that is the number of spaces for which is_free() = False. It saves that number in member node_nb[lvl].
Further having this number ready in member node_nb[lvl] and its counterpart (the number of free nodes calculated as the difference between total nodes and the member free_nodes_nb(lvl), class Map also provide method free_nodes_list(lvl) which returns a list of all the ids of level lvl.
Important: these data keeps in mind that some IPv4 addresses are not valid, for example 192.168.* or 224.* etc.
In map class, the attribute me saves its spaces, which is its Netsukuku-IP (nip).
A nip is indicated as a sequence of IDs for the different levels from 0 to the highest.
self.me = [1,1,168,192]
Note that the first element in the sequence is level 0 (id of the single node)
Another way to represent a space in the map is the integer, called simply ip, calculated as 192*2563+168*2562+1*2561+1*2560.
To convert from a notation to the other it is possible to use methods ip_to_nip and nip_to_ip.
To describe other functionalities, now we suppose to have another address saved in variable nip.
nip = [2,2,168,192]
Method is_in_level tell if a certain node (or gnode) is in the same gnode of me of level x. In this case self.is_in_level(nip,0) would return False;
while self.is_in_level(nip,1) would return True.
Method nip_cmp tell which is the highest different level between two Netsukuku-IP. This research starts from the last element of the sequence (levels -1). In this case
should return 1.
Method lvlid_to_nip(lvl, id) returns nip of the node with id id and level lvl. This nip is generated taking self.me, replacing level lvl with id value, and setting to 0 all levels under lvl.
pack e merge
Class Map provides a method map_data_pack which returns a structure containing all data of this map (except dimensions levels and gsize which are considered to be known a priori).
To be more precise, it is a tuple of 3 elements: object NIP (self.me), a copy of the list of lists of objects dataclass, a copy of the list of number of non-free objects.
Note that, to pass this structure to a remotable method, it's needed that the class used as dataclass is registered as serializable with module rencode.
Furthermore provides method map_data_merge which uses as argument a structure of the same format generated by map_data_pack.
This method verifies at which level (call it l) is the gnode in common between its attribute me and the one of the received map. To calculate this it uses nip_cmp which returns the highest different level. Values of received map whose index is more than or equal to l represents all the nodes that me and the node of received map have in common. Values whose index is lower than l have no mean for me.
When it is established which values of received map have a mean for me, method map_data_merge reset object map with only that nodes and reset all lower levels.
Method name, merge, can be misleading: it does not mean that old map data are mantained. The only info to remain is old NIP, and all data coming from received map (normally it is received from a remote node) became significant when referred to object NIP.
It is used in class MapP2P, derived from Map, when class P2PAll (see module P2P) retrieves map of partecipants from one of it neighbours through remotable method pid_getall.
Another class derived from Map, class MapCache of module coord, declares remotable method map_data_merge itself, and class Coord uses it to pass data forma a Coordinator Node to its successor.