LCOV - code coverage report
Current view: top level - src - PrefixTable.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 35 73 47.9 %
Date: 2010-12-13 Functions: 7 11 63.6 %
Branches: 20 53 37.7 %

           Branch data     Line data    Source code
       1                 :            : // $Id: PrefixTable.cc 1016 2005-01-31 21:23:50Z vern $
       2                 :            : 
       3                 :            : #include "PrefixTable.h"
       4                 :            : 
       5                 :            : // IPv4 version.
       6                 :       4235 : inline static prefix_t* make_prefix(const uint32 addr, int width)
       7                 :            :         {
       8                 :       4235 :         prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t));
       9                 :            : 
      10                 :       4235 :         memcpy(&prefix->add.sin, &addr, sizeof(prefix->add.sin)) ;
      11                 :       4235 :         prefix->family = AF_INET;
      12                 :       4235 :         prefix->bitlen = width;
      13                 :       4235 :         prefix->ref_count = 1;
      14                 :            : 
      15                 :       4235 :         return prefix;
      16                 :            :         }
      17                 :            : 
      18                 :            : #ifdef BROv6
      19                 :            : inline static prefix_t* make_prefix(const uint32* addr, int width)
      20                 :            :         {
      21                 :            :         prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t));
      22                 :            : 
      23                 :            :         memcpy(&prefix->add.sin6, addr, 4 * sizeof(uint32));
      24                 :            :         prefix->family = AF_INET6;
      25                 :            :         prefix->bitlen = width;
      26                 :            :         prefix->ref_count = 1;
      27                 :            : 
      28                 :            :         return prefix;
      29                 :            :         }
      30                 :            : #endif
      31                 :            : 
      32                 :         14 : void* PrefixTable::Insert(const_addr_type addr, int width, void* data)
      33                 :            :         {
      34                 :         14 :         prefix_t* prefix = make_prefix(addr, width);
      35                 :         14 :         patricia_node_t* node = patricia_lookup(tree, prefix);
      36                 :         14 :         Deref_Prefix(prefix);
      37                 :            : 
      38         [ -  + ]:         14 :         if ( ! node )
      39                 :          0 :                 internal_error("Cannot create node in patricia tree");
      40                 :            : 
      41                 :         14 :         void* old = node->data;
      42                 :            : 
      43                 :            :         // If there is no data to be associated with addr, we take the
      44                 :            :         // node itself.
      45         [ +  - ]:         14 :         node->data = data ? data : node;
      46                 :            : 
      47                 :         14 :         return old;
      48                 :            :         }
      49                 :            : 
      50                 :         14 : void* PrefixTable::Insert(const Val* value, void* data)
      51                 :            :         {
      52                 :            :         // [elem] -> elem
      53 [ +  + ][ +  - ]:         14 :         if ( value->Type()->Tag() == TYPE_LIST &&
                 [ +  + ]
      54                 :            :              value->AsListVal()->Length() == 1 )
      55                 :          1 :                 value = value->AsListVal()->Index(0);
      56                 :            : 
      57      [ -  +  - ]:         14 :         switch ( value->Type()->Tag() ) {
      58                 :            :         case TYPE_ADDR:
      59                 :          0 :                 return Insert(value->AsAddr(), NUM_ADDR_WORDS * 32, data);
      60                 :            :                 break;
      61                 :            : 
      62                 :            :         case TYPE_SUBNET:
      63                 :            :                 return Insert(value->AsSubNet()->net,
      64                 :         14 :                                 value->AsSubNet()->width, data);
      65                 :            :                 break;
      66                 :            : 
      67                 :            :         default:
      68                 :         14 :                 internal_error("Wrong index type for PrefixTable");
      69                 :            :                 return 0;
      70                 :            :         }
      71                 :            :         }
      72                 :            : 
      73                 :       4221 : void* PrefixTable::Lookup(const_addr_type addr, int width, bool exact) const
      74                 :            :         {
      75                 :       4221 :         prefix_t* prefix = make_prefix(addr, width);
      76                 :            :         patricia_node_t* node =
      77                 :            :                 exact ? patricia_search_exact(tree, prefix) :
      78         [ +  + ]:       4221 :                         patricia_search_best(tree, prefix);
      79                 :            : 
      80                 :       4221 :         Deref_Prefix(prefix);
      81         [ -  + ]:       4221 :         return node ? node->data : 0;
      82                 :            :         }
      83                 :            : 
      84                 :       4221 : void* PrefixTable::Lookup(const Val* value, bool exact) const
      85                 :            :         {
      86                 :            :         // [elem] -> elem
      87 [ +  + ][ +  - ]:       4221 :         if ( value->Type()->Tag() == TYPE_LIST &&
                 [ +  + ]
      88                 :            :              value->AsListVal()->Length() == 1 )
      89                 :          1 :                 value = value->AsListVal()->Index(0);
      90                 :            : 
      91      [ +  +  - ]:       4221 :         switch ( value->Type()->Tag() ) {
      92                 :            :         case TYPE_ADDR:
      93                 :       4207 :                 return Lookup(value->AsAddr(), NUM_ADDR_WORDS * 32, exact);
      94                 :            :                 break;
      95                 :            : 
      96                 :            :         case TYPE_SUBNET:
      97                 :            :                 return Lookup(value->AsSubNet()->net,
      98                 :         14 :                                 value->AsSubNet()->width, exact);
      99                 :            :                 break;
     100                 :            : 
     101                 :            :         default:
     102                 :            :                 internal_error(fmt("Wrong index type %d for PrefixTable",
     103                 :       4221 :                                         value->Type()->Tag()));
     104                 :            :                 return 0;
     105                 :            :         }
     106                 :            :         }
     107                 :            : 
     108                 :          0 : void* PrefixTable::Remove(const_addr_type addr, int width)
     109                 :            :         {
     110                 :          0 :         prefix_t* prefix = make_prefix(addr, width);
     111                 :          0 :         patricia_node_t* node = patricia_search_exact(tree, prefix);
     112                 :          0 :         Deref_Prefix(prefix);
     113                 :            : 
     114         [ #  # ]:          0 :         if ( ! node )
     115                 :          0 :                 return 0;
     116                 :            : 
     117                 :          0 :         void* old = node->data;
     118                 :          0 :         patricia_remove(tree, node);
     119                 :            : 
     120                 :          0 :         return old;
     121                 :            :         }
     122                 :            : 
     123                 :          0 : void* PrefixTable::Remove(const Val* value)
     124                 :            :         {
     125                 :            :         // [elem] -> elem
     126 [ #  # ][ #  # ]:          0 :         if ( value->Type()->Tag() == TYPE_LIST &&
                 [ #  # ]
     127                 :            :              value->AsListVal()->Length() == 1 )
     128                 :          0 :                 value = value->AsListVal()->Index(0);
     129                 :            : 
     130      [ #  #  # ]:          0 :         switch ( value->Type()->Tag() ) {
     131                 :            :         case TYPE_ADDR:
     132                 :          0 :                 return Remove(value->AsAddr(), NUM_ADDR_WORDS * 32);
     133                 :            :                 break;
     134                 :            : 
     135                 :            :         case TYPE_SUBNET:
     136                 :          0 :                 return Remove(value->AsSubNet()->net, value->AsSubNet()->width);
     137                 :            :                 break;
     138                 :            : 
     139                 :            :         default:
     140                 :          0 :                 internal_error("Wrong index type for PrefixTable");
     141                 :            :                 return 0;
     142                 :            :         }
     143                 :            :         }
     144                 :            : 
     145                 :          0 : PrefixTable::iterator PrefixTable::InitIterator()
     146                 :            :         {
     147                 :            :         iterator i;
     148                 :          0 :         i.Xsp = i.Xstack;
     149                 :          0 :         i.Xrn = tree->head;
     150                 :          0 :         i.Xnode = 0;
     151                 :            :         return i;
     152                 :            :         }
     153                 :            : 
     154                 :          0 : void* PrefixTable::GetNext(iterator* i)
     155                 :            :         {
     156                 :          0 :         while ( 1 )
     157                 :            :                 {
     158                 :          0 :                 i->Xnode = i->Xrn;
     159         [ #  # ]:          0 :                 if ( ! i->Xnode )
     160                 :          0 :                         return 0;
     161                 :            : 
     162         [ #  # ]:          0 :                 if ( i->Xrn->l )
     163                 :            :                         {
     164         [ #  # ]:          0 :                         if (i->Xrn->r)
     165                 :          0 :                                 *i->Xsp++ = i->Xrn->r;
     166                 :            : 
     167                 :          0 :                         i->Xrn = i->Xrn->l;
     168                 :            :                         }
     169                 :            : 
     170         [ #  # ]:          0 :                 else if ( i->Xrn->r )
     171                 :          0 :                         i->Xrn = i->Xrn->r;
     172                 :            : 
     173         [ #  # ]:          0 :                 else if (i->Xsp != i->Xstack)
     174                 :          0 :                         i->Xrn = *(--i->Xsp);
     175                 :            : 
     176                 :            :                 else
     177                 :          0 :                         i->Xrn = (patricia_node_t*) 0;
     178                 :            : 
     179         [ #  # ]:          0 :                 if ( i->Xnode->prefix )
     180                 :          0 :                         return (void*) i->Xnode->data;
     181                 :            :                 }
     182                 :            : 
     183                 :            :         // Not reached.
     184 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8