[cvs] / netsukuku / src / bmap.c Repository:
ViewVC logotype

View of /netsukuku/src/bmap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.27 - (download) (as text) (annotate)
Sat Jun 24 08:12:14 2006 UTC (4 years, 2 months ago) by alpt
Branch: MAIN
CVS Tags: HEAD
Changes since 1.26: +1 -3 lines
It almost works, but it hangs on get_ext_maps()
    1 /* This file is part of Netsukuku
    2  * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
    3  *
    4  * This source code is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License as published
    6  * by the Free Software Foundation; either version 2 of the License,
    7  * or (at your option) any later version.
    8  *
    9  * This source code is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   12  * Please refer to the GNU Public License for more details.
   13  *
   14  * You should have received a copy of the GNU Public License along with
   15  * this source code; if not, write to:
   16  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   17  *
   18  * --
   19  * bmap.c:
   20  * Border node map code.
   21  */
   22 
   23 #include "includes.h"
   24 
   25 #include "common.h"
   26 #include "inet.h"
   27 #include "endianness.h"
   28 #include "map.h"
   29 #include "gmap.h"
   30 #include "bmap.h"
   31 
   32 void bmap_levels_init(u_char levels, map_bnode ***bmap, u_int **bmap_nodes)
   33 {
   34   *bmap=xmalloc(sizeof(map_bnode *) * levels);
   35   *bmap_nodes=(u_int *)xmalloc(sizeof(u_int) * levels);
   36 
   37   setzero(*bmap, sizeof(map_bnode *) * levels);
   38   bmap_counter_reset(levels, *bmap_nodes);
   39 }
   40 
   41 void bmap_levels_free(map_bnode **bmap, u_int *bmap_nodes)
   42 {
   43   xfree(bmap);
   44   xfree(bmap_nodes);
   45 }
   46 
   47 void bmap_counter_init(u_char levels, u_int **bnodes_closed, u_int **bnodes_opened)
   48 {
   49   *bnodes_closed=(u_int *)xmalloc(sizeof(u_int) * levels);
   50   *bnodes_opened=(u_int *)xmalloc(sizeof(u_int) * levels);
   51 
   52   bmap_counter_reset(levels, *bnodes_closed);
   53   bmap_counter_reset(levels, *bnodes_opened);
   54 }
   55 
   56 void bmap_counter_free(u_int *bnodes_closed, u_int *bnodes_opened)
   57 {
   58   xfree(bnodes_closed);
   59   xfree(bnodes_opened);
   60 }
   61 
   62 void bmap_counter_reset(u_char levels, u_int *counter)
   63 {
   64   setzero(counter, sizeof(u_int) * levels);
   65 }
   66 
   67 /*
   68  * map_add_bnode: It adds a new bnode in the `bmap' and then returns its position
   69  * in the bmap. It also increments the `*bmap_nodes' counter. The bnode_ptr is set
   70  * to `bnode' and the links to `links'.
   71  * Note that the `bmap' argument must be an adress of a pointer.
   72  */
   73 int map_add_bnode(map_bnode **bmap, u_int *bmap_nodes, u_int bnode, u_int links)
   74 {
   75   map_bnode *bnode_map;
   76   u_int bm;
   77 
   78   bm=*bmap_nodes;
   79   (*bmap_nodes)++;
   80   if(!bm)
   81     *bmap=xmalloc(sizeof(map_bnode));
   82   else
   83     *bmap=xrealloc(*bmap, sizeof(map_bnode) * *bmap_nodes);
   84 
   85   bnode_map=*bmap;
   86   setzero(bnode_map, sizeof(map_bnode));
   87   bnode_map[bm].bnode_ptr=bnode;
   88   bnode_map[bm].links=links;
   89   return bm;
   90 }
   91 
   92 /*
   93  * map_bnode_del: It deletes the `bnode' in the `bmap' which has `bmap_nodes'.
   94  * It returns the newly rescaled `bmap'.
   95  * It returns 0 if the `bmap' doesn't exist anymore.*/
   96 map_bnode *map_bnode_del(map_bnode *bmap, u_int *bmap_nodes,  map_bnode *bnode)
   97 {
   98   map_node_del((map_node *)bnode);
   99 
  100   if( ((char *)bnode-(char *)bmap)/sizeof(map_bnode) != (*bmap_nodes)-1 )
  101     memcpy(bnode, &bmap[*bmap_nodes-1], sizeof(map_bnode));
  102 
  103   (*bmap_nodes)--;
  104   if(*bmap_nodes)
  105     return xrealloc(bmap, (*bmap_nodes) * sizeof(map_bnode));
  106   else {
  107     *bmap_nodes=0;
  108     xfree(bmap);
  109     return 0;
  110   }
  111 }
  112 
  113 /*
  114  * bmap_del_rnode_by_level: it is pretty specific, it deletes all the rnodes
  115  * of `bnode' which point to a gnode located in a level not equal to `level'.
  116  * The number of rnode deleted is returned.
  117  * `total_levels' must be equal to the maximum levels
  118  * available (use FAMILY_LVLS).
  119  */
  120 int bmap_del_rnode_by_level(map_bnode *bnode, int level, map_gnode **ext_map,
  121     int total_levels)
  122 {
  123   map_gnode *gn;
  124   int i, ret=0, lvl;
  125 
  126 
  127   for(i=0; i < bnode->links; i++) {
  128     gn=(map_gnode *)bnode->r_node[i].r_node;
  129     lvl=extmap_find_level(ext_map, gn, total_levels);
  130 
  131     if(lvl != level) {
  132       rnode_del(bnode, i);
  133       ret++;
  134     }
  135   }
  136 
  137   return ret;
  138 }
  139 
  140 /*
  141  * map_find_bnode: Find the given `node' (in the pos_from_node() format) in the
  142  * given map_bnode `bmap'.
  143  */
  144 int map_find_bnode(map_bnode *bmap, int bmap_nodes, int node)
  145 {
  146   int e;
  147 
  148   for(e=0; e<bmap_nodes; e++)
  149     if(bmap[e].bnode_ptr == node)
  150       return e;
  151 
  152   return -1;
  153 }
  154 
  155 /*
  156  * map_find_bnode_rnode: Find the first bnode in the `bmap' which has a rnode
  157  * which points to `n'. If it is found the pos of the bnode in the `bmap' is
  158  * returned, otherwise -1 is the return value.
  159  */
  160 int map_find_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n)
  161 {
  162   int e;
  163 
  164   for(e=0; e<bmap_nodes; e++)
  165     if(rnode_find((map_node *)&bmap[e], (map_node *)n) != -1)
  166       return e;
  167 
  168   return -1;
  169 }
  170 
  171 /*
  172  * map_count_bnode_rnode: counts how many bnode which have a rnode which
  173  * points to `n' there are in `bmap'.
  174  */
  175 int map_count_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n)
  176 {
  177   int e, i;
  178 
  179   for(i=0, e=0; i<bmap_nodes; i++)
  180     if(rnode_find((map_node *)&bmap[i], (map_node *)n) != -1)
  181       e++;
  182 
  183   return e;
  184 }
  185 
  186 /*
  187  * bmaps_count_bnode_rnode: applies map_count_bnode_rnode() to each level of
  188  * `bmap' and returns the sum of the results.
  189  * `levels' are the total levels of `bmap'.
  190  */
  191 int bmaps_count_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n)
  192 {
  193   int i, e;
  194 
  195   for(i=0, e=0; i<levels; i++)
  196     e+=map_count_bnode_rnode(bmap[i], bmap_nodes[i], n);
  197 
  198   return e;
  199 }
  200 
  201 /*
  202  * map_del_bnode_rnode: deletes all the rnodes of the bnode, present in `bmap',
  203  * which points to `n' and deletes the bnodes remained empty.
  204  * `bmap' is the address of the pointer to the bmap.
  205  * It returns the number of rnodes deleted.
  206  */
  207 int map_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, void *n)
  208 {
  209   map_bnode *bm;
  210   int e, p, ret=0;
  211 
  212   bm=*bmap;
  213   for(e=0; e < *bmap_nodes; e++) {
  214     if((p=rnode_find((map_node *)&bm[e], (map_node *)n)) != -1) {
  215       rnode_del(&bm[e], p);
  216 
  217       if(!bm[e].links) {
  218         *bmap=map_bnode_del(*bmap,(u_int*)bmap_nodes, &bm[e]);
  219         bm=*bmap;
  220       }
  221       ret++;
  222     }
  223   }
  224 
  225   return ret;
  226 }
  227 
  228 /*
  229  * bmaps_del_bnode_rnode: applies map_del_bnode_rnode() to each level of
  230  * `bmap'.
  231  * `levels' are the total levels of `bmap'.
  232  * It returns the total number of rnodes deleted
  233  */
  234 int bmaps_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n)
  235 {
  236   int i, e;
  237 
  238   for(i=0, e=0; i<levels; i++)
  239     e+=map_del_bnode_rnode(&bmap[i], &bmap_nodes[i], n);
  240 
  241   return e;
  242 }
  243 
  244 /*
  245  * map_set_bnode_flag: sets the `flags' to all the `bmap_nodes'# present in
  246  * `bmap'.
  247  */
  248 void map_set_bnode_flag(map_bnode *bmap, int bmap_nodes, int flags)
  249 {
  250   int e;
  251   for(e=0; e<bmap_nodes; e++)
  252     bmap[e].flags|=flags;
  253 }
  254 
  255 /*
  256  * bmaps_set_bnode_flag: sets the `flags' to all the bnodes present in the
  257  * `levels'#  `bmap'.
  258  */
  259 void bmaps_set_bnode_flag(map_bnode **bmap, int *bmap_nodes, int levels, int flags)
  260 {
  261   int i;
  262 
  263   for(i=0; i<levels; i++)
  264     map_set_bnode_flag(bmap[i], bmap_nodes[i], flags);
  265 }
  266 
  267 /*
  268  * pack_all_bmaps: It creates the block of all the `bmaps' which have
  269  * `bmap_nodes' nodes. `ext_map' and `quadg' are the structs referring
  270  * to the external map. In `pack_sz' is stored the size of the block.
  271  * The address pointing to the block is returned otherwise 0 is given.
  272  * The package will be in network order.
  273  */
  274 char *
  275 pack_all_bmaps(map_bnode **bmaps,  u_int *bmap_nodes, map_gnode **ext_map,
  276     quadro_group quadg, size_t *pack_sz)
  277 {
  278   struct bnode_maps_hdr bmaps_hdr;
  279   size_t sz, tmp_sz[BMAP_LEVELS(quadg.levels)];
  280   char *pack[BMAP_LEVELS(quadg.levels)], *final_pack, *buf;
  281   u_char level;
  282 
  283   *pack_sz=0;
  284 
  285   for(level=0; level < BMAP_LEVELS(quadg.levels); level++) {
  286     pack[level]=pack_map((map_node *)bmaps[level], (int *)ext_map[_EL(level+1)],
  287         bmap_nodes[level], 0, &sz);
  288     tmp_sz[level]=sz;
  289     (*pack_sz)+=sz;
  290   }
  291 
  292   bmaps_hdr.levels=BMAP_LEVELS(quadg.levels);
  293   bmaps_hdr.bmaps_block_sz=*pack_sz;
  294   (*pack_sz)+=sizeof(struct bnode_maps_hdr);
  295 
  296   final_pack=xmalloc((*pack_sz));
  297   memcpy(final_pack, &bmaps_hdr, sizeof(struct bnode_maps_hdr));
  298   ints_host_to_network(final_pack, bnode_maps_hdr_iinfo);
  299 
  300   buf=final_pack+sizeof(struct bnode_maps_hdr);
  301   for(level=0; level < BMAP_LEVELS(quadg.levels); level++) {
  302     memcpy(buf, pack[level], tmp_sz[level]);
  303     buf+=tmp_sz[level];
  304     xfree(pack[level]);
  305   }
  306 
  307   return final_pack;
  308 }
  309 
  310 /*
  311  * unpack_all_bmaps: Given a block `pack' of size `pack_sz' containing `levels'
  312  * it unpacks each bnode map it finds in it.
  313  * `ext_map' is the external map used by the new bmaps.
  314  * In `bmap_nodes' unpack_all_bmaps stores the address of the newly xmallocated
  315  * array of u_int. Each bmap_nodes[x] contains the number of nodes of the bmap
  316  * of level x.
  317  * `maxbnodes' is the maximum number of nodes each bmap can contain,
  318  * while `maxbnode_rnodeblock' is the maximum number of rnodes each node can
  319  * contain.
  320  * On error 0 is returned.
  321  * Note: `pack' will be modified during the unpacking.
  322  */
  323 map_bnode **
  324 unpack_all_bmaps(char *pack, u_char max_levels, map_gnode **ext_map,
  325     u_int **bmap_nodes, int maxbnodes, int maxbnode_rnodeblock)
  326 {
  327   struct bnode_maps_hdr *bmaps_hdr;
  328   struct bnode_map_hdr *bmap_hdr;
  329   map_bnode **bmap, *unpacked_bmap;
  330   size_t bblock_sz, pack_sz;
  331   int i,e=0;
  332   char *bblock, *buf;
  333   u_char levels;
  334 
  335   bmaps_hdr=(struct bnode_maps_hdr *)pack;
  336   ints_network_to_host(bmaps_hdr, bnode_maps_hdr_iinfo);
  337 
  338   levels=bmaps_hdr->levels;
  339   pack_sz=bmaps_hdr->bmaps_block_sz;
  340 
  341   if(levels > max_levels || pack_sz < sizeof(struct bnode_maps_hdr))
  342     return 0;
  343 
  344   bmap_levels_init(levels, &bmap, bmap_nodes);
  345 
  346   buf=pack+sizeof(struct bnode_maps_hdr);
  347   for(i=0; i<levels; i++) {
  348     bmap_hdr=(struct bnode_map_hdr *)buf;
  349     if(!bmap_hdr->bnode_map_sz) {
  350       buf+=sizeof(struct bnode_map_hdr);
  351       continue;
  352     }
  353 
  354     /*Extracting the map...*/
  355     bblock=(char *)bmap_hdr;
  356     unpacked_bmap=unpack_map(bblock, (int *)ext_map[_EL(i+1)], 0,
  357         maxbnodes, maxbnode_rnodeblock);
  358     if(!unpacked_bmap) {
  359       error("Cannot unpack the bnode_map at level %d ! Skipping...", i);
  360       e++;
  361       continue;
  362     }
  363 
  364     (*bmap_nodes)[i]=bmap_hdr->bnode_map_sz/MAP_BNODE_PACK_SZ;
  365     bblock_sz=INT_MAP_BLOCK_SZ(bmap_hdr->bnode_map_sz, bmap_hdr->rblock_sz);
  366 
  367     bmap[i]=unpacked_bmap;
  368 
  369     buf+=bblock_sz;
  370   }
  371 
  372   if(e == levels)
  373     /* Not a single map was restored */
  374     return 0;
  375 
  376   return bmap;
  377 }
  378 
  379 /* * *  save/load bnode_map * * */
  380 
  381 /*
  382  * save_bmap: It saves the bnode maps `bmaps' in `file'. The each `bmaps[x]' has
  383  * `bmap_nodes[x]' nodes. `ext_map' is the pointer to the external map the bmap is
  384  * referring to.
  385  */
  386 int save_bmap(map_bnode **bmaps, u_int *bmap_nodes, map_gnode **ext_map,
  387     quadro_group quadg, char *file)
  388 {
  389   FILE *fd;
  390   char *pack;
  391   size_t pack_sz;
  392 
  393 
  394   pack=pack_all_bmaps(bmaps, bmap_nodes, ext_map, quadg, &pack_sz);
  395   if(!pack_sz || !pack)
  396     return 0;
  397 
  398   if((fd=fopen(file, "w"))==NULL) {
  399     error("Cannot save the bnode_map in %s: %s", file, strerror(errno));
  400     return -1;
  401   }
  402   fwrite(pack, pack_sz, 1, fd);
  403 
  404   xfree(pack);
  405   fclose(fd);
  406   return 0;
  407 }
  408 
  409 /*
  410  * load_bmap: It loads all the bnode maps from `file' and returns the address
  411  * of the array of pointer to the loaded bmaps. `ext_map' is the external maps
  412  * the bmap shall refer to. In `bmap_nodes' the address of the u_int array, used
  413  * to count the nodes in each bmaps, is stored. On error 0 is returned.
  414  */
  415 map_bnode **load_bmap(char *file, map_gnode **ext_map, u_char max_levels, u_int **bmap_nodes)
  416 {
  417   map_bnode **bmap=0;
  418   FILE *fd;
  419   struct bnode_maps_hdr bmaps_hdr;
  420   size_t pack_sz;
  421   u_char levels;
  422   char *pack=0;
  423 
  424   if((fd=fopen(file, "r"))==NULL) {
  425     error("Cannot load the bmap from %s: %s", file, strerror(errno));
  426     return 0;
  427   }
  428 
  429   if(!fread(&bmaps_hdr, sizeof(struct bnode_maps_hdr), 1, fd))
  430     goto finish;
  431 
  432   ints_network_to_host(&bmaps_hdr, bnode_maps_hdr_iinfo);
  433   levels=bmaps_hdr.levels;
  434   pack_sz=bmaps_hdr.bmaps_block_sz;
  435   if(levels > max_levels || pack_sz < sizeof(struct bnode_maps_hdr))
  436     goto finish;
  437 
  438   /* Extracting the map... */
  439   rewind(fd);
  440   pack=xmalloc(pack_sz);
  441   if(!fread(pack, pack_sz, 1, fd))
  442     goto finish;
  443 
  444   bmap=unpack_all_bmaps(pack, max_levels, ext_map, bmap_nodes,
  445       MAXGROUPNODE, MAXBNODE_RNODEBLOCK);
  446 
  447 finish:
  448   fclose(fd);
  449   if(pack)
  450     xfree(pack);
  451   if(!bmap)
  452     error("Malformed bmap file. Cannot load the bnode maps.");
  453   return bmap;
  454 }

alpt (at) freaknet (dot) org
ViewVC Help
Powered by ViewVC 1.1-dev