vclass.cc 2.88 KB
Newer Older
Robert Ricci's avatar
Robert Ricci committed
1
/*
2
 * Copyright (c) 2000-2006 University of Utah and the Flux Group.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 
 * {{{EMULAB-LICENSE
 * 
 * This file is part of the Emulab network testbed software.
 * 
 * This file is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 * 
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * }}}
Robert Ricci's avatar
Robert Ricci committed
22 23
 */

24 25
static const char rcsid[] = "$Id: vclass.cc,v 1.13 2009-05-20 18:06:08 tarunp Exp $";

26
#include "port.h"
Leigh B. Stoller's avatar
Leigh B. Stoller committed
27

28
#include <stdlib.h>
29 30 31

#include <boost/config.hpp>
#include <boost/utility.hpp>
32
#include BOOST_PMAP_HEADER
33 34 35 36
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>

using namespace boost;
37 38 39

#include "common.h"
#include "vclass.h"
40 41
#include "delay.h"
#include "physical.h"
42 43
#include "virtual.h"

44 45
name_vclass_map vclass_map;

46
void tb_vclass::add_type(fstring type)
47
{
48
  members[type]=0;
49
  if (dominant.empty() ||
50
      (members[dominant] == 0)) {
51 52 53 54
    dominant = type;
  }
}

55
bool tb_vclass::has_type(fstring type) const {
56 57 58 59
    return (members.find(type) != members.end());
}


60
double tb_vclass::assign_node(fstring type)
61 62
{
  double new_score = score;
63
  members[type] += 1;
64 65

  if (type != dominant) {
66
    if (members[dominant] != 0) {
67 68
      new_score = weight;
    }
69
    if (members[type] > members[dominant]) {
70 71 72 73 74 75 76 77 78
      dominant = type;
    }
  }

  double delta = new_score-score;
  score=new_score;
  return delta;
}

79
double tb_vclass::unassign_node(fstring type)
80 81
{
  double new_score = 0;
82
  members[type] -= 1;
83 84

  int curmax = 0;
85 86 87
  for (members_map::iterator dit=members.begin();
       dit != members.end();++dit) {
    int n = (*dit).second;
88 89 90 91 92
    if (n > curmax) {
      if (curmax != 0) {
	new_score = weight;
      }
      curmax = n;
93
      dominant = (*dit).first;
94 95 96 97 98 99 100 101
    }
  }
  
  double delta = new_score-score;
  score=new_score;
  return delta;
}

102
fstring tb_vclass::choose_type() const
103
{
104 105
  // This may take some tweaking - i.e. might want to make more
  // efficient, although members is usually a very small hash.
106
  if (RANDOM()%2 == 0) {
107 108
    return dominant;
  }
109
  int r = RANDOM()%members.size();
110
  members_map::const_iterator dit;
111
  for (dit=members.begin();dit != members.end();++dit) {
112 113 114
    if (r == 0) break;
    r--;
  }
115
  return (*dit).first;
116 117
}

118 119
bool tb_vclass::empty() const {
    members_map::const_iterator dit;
120 121 122 123 124 125
    for (dit=members.begin();dit != members.end();++dit) {
        if ((*dit).second > 0) {
            return false;
        }
    }
    return true;
126
}