summaryrefslogtreecommitdiff
path: root/src/generic/apt/aptitude_resolver_cost_settings.h
blob: fc45252537d4166ea366c248f6995bd0e9830c3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/** \file aptitude_resolver_cost_settings.h */ // -*-c++


// Copyright (C) 2010 Daniel Burrows

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.

// This program 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
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING.  If not, write to
// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.

#ifndef APTITUDE_RESOLVER_COST_SETTINGS_H
#define APTITUDE_RESOLVER_COST_SETTINGS_H

#include "aptitude_resolver_cost_types.h"

#include <generic/problemresolver/cost.h>

#include <boost/shared_ptr.hpp>
#include <vector>

class aptitude_resolver;
class aptitude_resolver_version;

/** \brief Core data structure for keeping track of which cost
 *  components are active and how they interact.
 *
 *  Only active cost components have their costs actually registered
 *  in the resolver.  Also, this class knows how to parse and
 *  serialize the set of registered components.
 */
class aptitude_resolver_cost_settings
{
  // Hide the implementation.
  class settings_impl;

  boost::shared_ptr<settings_impl> impl;
public:
  /** \brief Reference to a single cost component.
   *
   *  Used to avoid unnecessary string lookups.
   */
  class component
  {
    // I use an integer instead of an iterator to avoid forcing every
    // other module to know the type of this object's internal
    // container.
    //
    // Note: internally, -1 is used to indicate that a component
    // doesn't affect any component of the resolver's cost structure.
    // These components are *also* stored in the settings object, to
    // ensure that they're used consistently, but they have no effect
    // on any resolver cost.
    int id;

    friend class aptitude_resolver_cost_settings;

    component(int _id)
      : id(_id)
    {
    }

  public:
    component()
      : id(-1)
    {
    }

    component(const component &other)
      : id(other.id)
    {
    }

    component &operator=(const component &other)
    {
      id = other.id;
      return *this;
    }

    // I don't implement a full complement of comparison / hash
    // operators because they aren't needed yet.
  };

  /** \brief Possible cost component types. */
  enum component_type
    {
      /** \brief The type of components that can be added together. */
      additive,
      /** \brief The type of components that can be increased stepwise
       *         via max().
       */
      maximized
    };

  /** \brief Validate the given cost settings and construct a cost
   *  settings object from it.
   *
   *  \param settings  The components of the cost.
   */
  explicit aptitude_resolver_cost_settings(const boost::shared_ptr<std::vector<cost_component_structure> > &settings);
  ~aptitude_resolver_cost_settings();

  /** \brief Test whether the given component is relevant to the cost
   *  settings.
   *
   *  If this returns \b false, then modifying this component has no
   *  effect; can be used to short-circuit some matching logic.
   */
  bool is_component_relevant(const component &component) const
  {
    return component.id >= 0;
  }

  /** \brief Write these settings to an ostream. */
  void dump(std::ostream &out) const;

  /** \brief Get or create a cost component.
   *
   *  \param name  The string that the returned component
   *               is bound to.
   *  \param type  The type of the returned component.
   *
   *  \throws CostTypeCheckFailure if this component has already been
   *  instantiated with an incompatible type.
   *
   *  \note this may modify the type of an existing component if its
   *  type couldn't be inferred from the cost settings string.
   */
  component get_or_create_component(const std::string &name,
				    component_type type);

  /** \brief Get a cost that adds a value to a cost component.
   *
   *  The cost component must have type "additive".
   */
  cost add_to_cost(const component &component,
                   int amt);

  /** \brief Get a cost that raises a cost component to an upper
   *  bound.
   *
   *  The cost component must have type "maximized".
   */
  cost raise_cost(const component &component,
                  int amt);
};

inline std::ostream &operator<<(std::ostream &out, const aptitude_resolver_cost_settings &settings)
{
  settings.dump(out);
  return out;
}

#endif // APTITUDE_RESOLVER_COST_SETTINGS_H