ChannelSelection.h 6.06 KB
Newer Older
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#ifndef COOLKERNEL_CHANNELSELECTION_H
#define COOLKERNEL_CHANNELSELECTION_H 1

// First of all, set/unset CORAL290, COOL300, COOL400 and COOL_HAS_CPP11 macros
#include "CoolKernel/VersionInfo.h"

// Include files
#include <limits>
#ifdef COOL400CPP11ENUM
#include <ostream>
#endif
#include <vector>
#include "CoolKernel/ChannelId.h"

namespace cool
{

  /** @class ChannelSelection ChannelSelection.h
   *
   *  Helper class to specify a selection of channels and their ordering
   *  for multi-channel bulk retrieval of IOVs.
   *
   *  So far, only selection of IOVs _within a given tag_ is supported (the
   *  choice of the selected tag is made outside the ChannelSelection class).
   *  Within each channel, IOVs can be browsed ordered by 'iovSince',
   *  and there is only one IOV valid at any given validity time.
   *
   *  @author Sven A. Schmidt, Andrea Valassi and Marco Clemencic
   *  @date   2005-08-08
   *///

  class ChannelSelection
  {

    friend class ChannelSelectionTest;

  public:

    /// Internal helper class for channel ranges. Ideally this class should
    /// be private but PyCool dictionary generation does not like that!

    class ChannelRange
    {

    public:

      // Required by PyCool
#ifdef COOL290CO
      ChannelRange()
        : m_firstChannel( 0 ) // Fix Coverity UNINIT_CTOR (bug #95363)
        , m_lastChannel( 0 ) {}
#else
      ChannelRange() {}
#endif

      ChannelRange( const ChannelId& firstChannel,
                    const ChannelId& lastChannel );

      ChannelId firstChannel() const;
      ChannelId lastChannel() const;
      bool inRange( const ChannelId& channel ) const;

    private:

      ChannelId m_firstChannel;
      ChannelId m_lastChannel;

    };

    /// There are two possible orders to browse IOVs (within a tag) across
    /// many channels: 'order by channel, since' and 'order by since, channel'.
    /// The second set of the ordering scheme lists the IOVs in reverse order.
#ifndef COOL400CPP11ENUM
    enum Order
#else
    enum class Order
#endif
    {
      channelBeforeSince, sinceBeforeChannel,
        channelBeforeSinceDesc, sinceDescBeforeChannel
        };

#ifdef COOL400CPP11ENUM
    // Overloaded operator<< for cool::ChannelSelection::Order
    inline friend std::ostream&
    operator<<( std::ostream& s, const cool::ChannelSelection::Order& order )
    {
      return s << (int)order;
    }
#endif

    /// Constructor to (implicitly) select IOVs from *all* channels
    /// with the given order (default is 'order by channel, since').
#ifndef COOL400CPP11ENUM
    explicit ChannelSelection( const Order& order = channelBeforeSince );
#else
    explicit ChannelSelection( const Order& order = Order::channelBeforeSince );
#endif

    /// Constructor to select IOVs for a given channel. This constructor is
    /// intended to be used to autoconvert ChannelId to a ChannelSelection.
    ChannelSelection( const ChannelId& channel );

    /// Constructor to select IOVs for channels within a given range
    /// with the given order (default is 'order by channel, since').
    ChannelSelection( const ChannelId& firstChannel,
                      const ChannelId& lastChannel,
#ifndef COOL400CPP11ENUM
                      const Order& order = channelBeforeSince
#else
                      const Order& order = Order::channelBeforeSince
#endif
                      );

    /// Constructor to select IOVs with a given channel name.
    ChannelSelection( const std::string& channelName,
#ifndef COOL400CPP11ENUM
                      const Order& order = channelBeforeSince
#else
                      const Order& order = Order::channelBeforeSince
#endif
                      );

    /// Returns true if selecting all channels.
    bool allChannels() const;

    /// Returns the first selected channel
    /// [std::numeric_limits<ChannelId>::min() if selecting all channels].
    ChannelId firstChannel() const;

    /// Returns the last selected channel
    /// [std::numeric_limits<ChannelId>::max() if selecting all channels].
    ChannelId lastChannel() const;

    /// Returns the selection order.
    Order order() const;

    /// Construct a selection to select *all* channels with the given order.
    static const
#ifndef COOL400CPP11ENUM
    ChannelSelection all( const Order& order = channelBeforeSince );
#else
    ChannelSelection all( const Order& order = Order::channelBeforeSince );
#endif

    /// Returns true if the given channel is in the selection
    bool inSelection( const ChannelId& channel ) const;

    /// Returns true if the given channelName is in the selection
    bool inSelection( const std::string& channelName ) const;

    /// Returns true if the selection is contiguous
    /// This is the case if every channel between the very first and the
    /// last of the selection ranges is in the selection.
    /// This method does not make any assumption about the granularity. The
    /// only requirement is that operator++ at the end of an internal channel
    /// range will step to the first channel of the next range and not 'land'
    /// on a ChannelId outside the selection.
    bool isContiguous() const;

    /// Adds a channel range to the selection
    /// For sake of simplicity, it is required that the range is added
    /// to the front or the back of the existing selection without overlap.
    void addRange( const ChannelId& firstChannel,
                   const ChannelId& lastChannel );

    /// Adds a channel to the selection
    void addChannel( const ChannelId& channel );

    /// Returns true is the ChannelSelection is numeric.
    bool isNumeric() const;

    /// Returns the channel name list
    const std::string& channelName() const;

    /// Returns the beginning of a const range iterator
    std::vector<ChannelRange>::const_iterator begin() const;

    /// Returns the end of a const range iterator
    std::vector<ChannelRange>::const_iterator end() const;

    /// Returns the range count
    unsigned int rangeCount() const;

  private:

    bool m_isNumeric;
    bool m_allChannels;
    std::vector<ChannelRange> m_ranges;
    std::string m_channelName;
    Order m_order;

  };

}
#endif // COOLKERNEL_CHANNELSELECTION_H