Changeset 715


Ignore:
Timestamp:
04/30/15 17:28:21 (9 years ago)
Author:
Kris Deugau
Message:

/trunk

Factor out a chunk of deleteBlock() (compact free blocks to the minimal
CIDR set) so we can reuse it in the coming mergeBlocks().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/cgi-bin/IPDB.pm

    r714 r715  
    150150
    151151
    152 # Let's initialize the globals.
     152## IPDB::_compactFree()
     153# Utility sub to compact a set of free block entries down to the minimum possible set of CIDR entries
     154# Not to be called outside of an eval{}!
     155sub _compactFree {
     156  my $dbh = shift;
     157
     158  my $parent = shift;
     159
     160  # Rather than having the caller provide all the details
     161  my $pinfo = getBlockData($dbh, $parent);
     162  my $ftype = (split //, $pinfo->{type})[1];
     163
     164# NetAddr::IP->compact() attempts to produce the smallest inclusive block
     165# from the caller and the passed terms.
     166# EG:  if you call $cidr->compact($ip1,$ip2,$ip3) when $cidr, $ip1, $ip2,
     167#       and $ip3 are consecutive /27's starting on .0 (.0-.31, .32-.63,
     168#       .64-.95, and .96-.128), you will get an array containing a single
     169#       /25 as element 0 (.0-.127).  Order is not important;  you could have
     170#       $cidr=.32/27, $ip1=.96/27, $ip2=.0/27, and $ip3=.64/27.
     171
     172##fixme: vrf
     173##fixme:  simplify since all containers now represent different "layers"/"levels"?
     174
     175  # set up the query to get the list of blocks to try to merge.
     176  my $sth = $dbh->prepare(q{
     177        SELECT cidr,id FROM freeblocks
     178        WHERE parent_id = ?
     179        ORDER BY masklen(cidr) DESC
     180        });
     181  $sth->execute($parent);
     182
     183  my (@rawfb, @combinelist, %rawid);
     184  my $i=0;
     185  # for each free block under $parent, push a NetAddr::IP object into one list, and
     186  # continuously use NetAddr::IP->compact to automagically merge netblocks as possible.
     187  while (my ($fcidr, $fid) = $sth->fetchrow_array) {
     188    my $testIP = new NetAddr::IP $fcidr;
     189    push @rawfb, $testIP;
     190    $rawid{"$testIP"} = $fid;  # $data[0] vs "$testIP" *does* make a difference for v6
     191    @combinelist = $testIP->compact(@combinelist);
     192  }
     193
     194  # now that we have the full list of "compacted" freeblocks, go back over
     195  # the list of raw freeblocks, and delete the ones that got merged.
     196  $sth = $dbh->prepare("DELETE FROM freeblocks WHERE id = ?");
     197  foreach my $rawfree (@rawfb) {
     198    next if grep { $rawfree == $_ } @combinelist;       # skip if the raw block is in the compacted list
     199    $sth->execute($rawid{$rawfree});
     200  }
     201
     202  # now we walk the new list of compacted blocks, and see which ones we need to insert
     203  $sth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,parent_id,master_id) VALUES (?,?,?,?,?)");
     204  foreach my $cme (@combinelist) {
     205    next if grep { $cme == $_ } @rawfb; # skip if the combined block was in the raw list
     206    $sth->execute($cme, $pinfo->{city}, $ftype, $parent, $pinfo->{master_id});
     207  }
     208
     209} # end _compactFree()
     210
     211
     212##
     213## Public subs
     214##
     215
     216
    153217## IPDB::initIPDBGlobals()
    154218# Initialize all globals.  Takes a database handle, returns a success or error code
     
    19982062        }
    19992063
    2000 ##fixme: vrf
    2001 ##fixme:  simplify since all containers now represent different "layers"/"levels"?
    2002         # set up the query to get the list of blocks to try to merge.
    2003         $sth = $dbh->prepare("SELECT cidr,id FROM freeblocks ".
    2004                 "WHERE parent_id = ? ".
    2005                 "ORDER BY masklen(cidr) DESC");
    2006 
    2007         $sth->execute($p_id);
    2008 
    2009 # NetAddr::IP->compact() attempts to produce the smallest inclusive block
    2010 # from the caller and the passed terms.
    2011 # EG:  if you call $cidr->compact($ip1,$ip2,$ip3) when $cidr, $ip1, $ip2,
    2012 #       and $ip3 are consecutive /27's starting on .0 (.0-.31, .32-.63,
    2013 #       .64-.95, and .96-.128), you will get an array containing a single
    2014 #       /25 as element 0 (.0-.127).  Order is not important;  you could have
    2015 #       $cidr=.32/27, $ip1=.96/27, $ip2=.0/27, and $ip3=.64/27.
    2016 
    2017         my (@rawfb, @combinelist, %rawid);
    2018         my $i=0;
    2019         # for each free block under $parent, push a NetAddr::IP object into one list, and
    2020         # continuously use NetAddr::IP->compact to automagically merge netblocks as possible.
    2021         while (my @data = $sth->fetchrow_array) {
    2022           my $testIP = new NetAddr::IP $data[0];
    2023           push @rawfb, $testIP;
    2024           $rawid{"$testIP"} = $data[1];  # $data[0] vs "$testIP" *does* make a difference for v6
    2025           @combinelist = $testIP->compact(@combinelist);
    2026         }
    2027 
    2028         # now that we have the full list of "compacted" freeblocks, go back over
    2029         # the list of raw freeblocks, and delete the ones that got merged.
    2030         $sth = $dbh->prepare("DELETE FROM freeblocks WHERE id = ?");
    2031         foreach my $rawfree (@rawfb) {
    2032           next if grep { $rawfree == $_ } @combinelist; # skip if the raw block is in the compacted list
    2033           $sth->execute($rawid{$rawfree});
    2034         }
    2035 
    2036         # now we walk the new list of compacted blocks, and see which ones we need to insert
    2037         $sth = $dbh->prepare("INSERT INTO freeblocks (cidr,city,routed,parent_id,master_id) VALUES (?,?,?,?,?)");
    2038         foreach my $cme (@combinelist) {
    2039           next if grep { $cme == $_ } @rawfb;   # skip if the combined block was in the raw list
    2040           $sth->execute($cme, $pcity, $ptype, $p_id, $binfo->{master_id});
    2041         }
     2064        # Walk the free blocks in the parent and reduce them to the minimal set of CIDR ranges necessary
     2065        _compactFree($dbh, $p_id);
    20422066
    20432067      } # done returning IPs to the appropriate place
Note: See TracChangeset for help on using the changeset viewer.