BDE 4.39.x Production Release
Loading...
Searching...
No Matches
ball_ruleset.h
Go to the documentation of this file.
1/// @file ball_ruleset.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_ruleset.h -*-C++-*-
8#ifndef INCLUDED_BALL_RULESET
9#define INCLUDED_BALL_RULESET
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_ruleset ball_ruleset
15/// @brief Provide a set of unique rules.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_ruleset
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_ruleset-purpose"> Purpose</a>
25/// * <a href="#ball_ruleset-classes"> Classes </a>
26/// * <a href="#ball_ruleset-description"> Description </a>
27/// * <a href="#ball_ruleset-thread-safety"> Thread Safety </a>
28/// * <a href="#ball_ruleset-usage"> Usage </a>
29///
30/// # Purpose {#ball_ruleset-purpose}
31/// Provide a set of unique rules.
32///
33/// # Classes {#ball_ruleset-classes}
34///
35/// - ball::RuleSet: container for unique rules
36///
37/// @see ball_rule
38///
39/// # Description {#ball_ruleset-description}
40/// This component provides a value-semantic container,
41/// `ball::RuleSet`, for storage and efficient retrieval of `ball::Rule`
42/// objects.
43///
44/// This component participates in the implementation of "Rule-Based Logging".
45/// For more information on how to use that feature, please see the package
46/// level documentation and usage examples for "Rule-Based Logging".
47///
48/// ## Thread Safety {#ball_ruleset-thread-safety}
49///
50///
51/// `ball::RuleSet` is *not* thread-safe in that multiple threads attempting to
52/// concurrently modify the same `ball::RuleSet` object will leave the object in
53/// an undefined state. To ensure thread-safety, concurrent accesses to a
54/// `ball::RuleSet` must be serialized by a mutex.
55///
56/// ## Usage {#ball_ruleset-usage}
57///
58///
59/// The following code fragments illustrate how to use a rule set.
60///
61/// We first create a rule whose pattern is `WEEKEND*` and whose threshold
62/// levels are all `ball::Severity::e_OFF` except the `pass-through` level. A
63/// `pass-through` level of `ball::Severity::e_INFO` indicates that whenever the
64/// rule is active and the severity equals or exceeds `ball::Severity::e_INFO`,
65/// log records will be passed to the observer:
66/// @code
67/// ball::Rule rule1("WEEKEND*", // pattern
68/// ball::Severity::e_OFF, // record level
69/// ball::Severity::e_INFO, // pass-through level
70/// ball::Severity::e_OFF, // trigger level
71/// ball::Severity::e_OFF); // triggerAll level
72/// @endcode
73/// Next, we create another rule having a different pattern, but the same
74/// threshold levels:
75/// @code
76/// ball::Rule rule2("WEEKDAY*", // pattern
77/// ball::Severity::e_OFF, // record level
78/// ball::Severity::e_INFO, // pass-through level
79/// ball::Severity::e_OFF, // trigger level
80/// ball::Severity::e_OFF); // triggerAll level
81/// @endcode
82/// We then create a `ball::RuleSet` object, add the two rules, and verify that
83/// rules were added correctly:
84/// @code
85/// ball::RuleSet ruleSet;
86/// assert(0 <= ruleSet.addRule(rule1));
87/// assert(0 <= ruleSet.addRule(rule2));
88/// assert(2 == ruleSet.numRules());
89/// @endcode
90/// Duplicate rules cannot be added:
91/// @code
92/// assert(-1 == ruleSet.addRule(rule1));
93/// assert(-1 == ruleSet.addRule(rule2));
94/// assert( 2 == ruleSet.numRules());
95/// @endcode
96/// Rules in a rule set can be looked up by the `ruleId` method:
97/// @code
98/// int i1 = ruleSet.ruleId(rule1);
99/// int i2 = ruleSet.ruleId(rule2);
100/// assert(0 <= i1); assert(i1 < ruleSet.maxNumRules());
101/// assert(0 <= i2); assert(i2 < ruleSet.maxNumRules());
102/// assert(i1 != i2);
103/// @endcode
104/// The `removeRule` method can be used to remove rules from a rule set.
105/// @code
106/// assert(ruleSet.removeRule(rule1));
107/// assert(1 == ruleSet.numRules());
108/// assert(ruleSet.ruleId(rule1) < 0);
109/// assert(ruleSet.ruleId(rule2) == i2);
110/// @endcode
111/// @}
112/** @} */
113/** @} */
114
115/** @addtogroup bal
116 * @{
117 */
118/** @addtogroup ball
119 * @{
120 */
121/** @addtogroup ball_ruleset
122 * @{
123 */
124
125#include <balscm_version.h>
126
127#include <ball_rule.h>
128
129#include <bslma_allocator.h>
131
133
134#include <bsl_unordered_set.h>
135#include <bsl_vector.h>
136
137
138namespace ball {
139
140 // =============
141 // class RuleSet
142 // =============
143
144/// This class manages a set of unique rule values. Rules may be added to
145/// or removed from the set; however, rules having duplicate values will
146/// not be added. For the definition of two rules having the same value,
147/// please refer to the function-level documentation associated with the
148/// `Rule::operator==` function.
149///
150/// See @ref ball_ruleset
151class RuleSet {
152
153 public:
154 // PUBLIC TYPES
155
156 /// `MaskType` is an alias for the fundamental integral type used to
157 /// indicate rule subsets compactly.
158 typedef unsigned int MaskType;
159
160 enum {
161 e_MAX_NUM_RULES = 8 * sizeof(MaskType)
162 // The maximum number of rules managed by this object.
163
164#ifndef BDE_OMIT_INTERNAL_DEPRECATED
167#endif // BDE_OMIT_INTERNAL_DEPRECATED
168 };
169
170 private:
171 // PRIVATE TYPES
172
173 /// Hash functor for `Rule`.
174 ///
175 /// See @ref ball_ruleset
176 struct RuleHash {
177
178 private:
179 // CLASS DATA
180 static int s_hashtableSize; // the default hashtable size
181
182 public:
183 // ACCESSORS
184
185 /// Return the hash value of the specified `rule`.
186 int operator()(const Rule& rule) const
187 {
188 return Rule::hash(rule, s_hashtableSize);
189 }
190 };
191
192 typedef bsl::unordered_set<Rule, RuleHash> HashtableType;
193
194 // DATA
195 HashtableType d_ruleHashtable; // the hash table that
196 // manages all the rules
197 // maintained by this rule set
198
199 bsl::vector<const Rule *> d_ruleAddresses; // secondary map between ids
200 // and the addresses of rules
201
202 bsl::vector<int> d_freeRuleIds; // rule Ids that are not being
203 // used
204
205 int d_numPredicates; // total number of predicates
206
207 // FRIENDS
208 friend bool operator==(const RuleSet&, const RuleSet&);
209 friend bool operator!=(const RuleSet&, const RuleSet&);
210 friend bsl::ostream& operator<<(bsl::ostream&, const RuleSet&);
211
212 public:
213 // CLASS METHODS
214
215 /// Return the maximum number of rules that can be simultaneously
216 /// maintained by this object.
217 static int maxNumRules();
218
219 /// Format the specified `mask` to the specified output `stream` at the
220 /// optionally specified indentation `level` and return a reference to
221 /// the modifiable `stream`. If `level` is specified, optionally
222 /// specify `spacesPerLevel`, the number of spaces per indentation level
223 /// for this and all of its nested objects. Each line is indented by
224 /// the absolute value of `level * spacesPerLevel`. If `level` is
225 /// negative, suppress indentation of the first line. If
226 /// `spacesPerLevel` is negative, suppress line breaks and format the
227 /// entire output on one line. If `stream` is initially invalid, this
228 /// operation has no effect.
229 static void printMask(bsl::ostream& stream,
230 MaskType mask,
231 int level = 0,
232 int spacesPerLevel = 0);
233
234 // TRAITS
236
237 // CREATORS
238
239 /// Create an empty rule set. Optionally specify a `basicAllocator`
240 /// used to supply memory. If `basicAllocator` is 0, the currently
241 /// installed default allocator will be used.
242 explicit RuleSet(bslma::Allocator *basicAllocator = 0);
243
244 /// Create a `RuleSet` object having the same value as that of the
245 /// specified `original` object. Optionally specify a `basicAllocator`
246 /// used to supply memory. If `basicAllocator` is 0, the currently
247 /// installed default allocator will be used.
248 RuleSet(const RuleSet& original, bslma::Allocator *basicAllocator = 0);
249
250 /// Destroy this object.
251 ~RuleSet() = default;
252
253 // MANIPULATOR
254
255 /// Create a new `Rule` object having the specified `value`. Return the
256 /// non-negative id of this non-modifiable object on success, and a
257 /// negative value otherwise. A return value of -1 indicates that
258 /// another rule having this value already exists. A return value of -2
259 /// indicates that the maximum number of rules for this rule set has
260 /// been reached.
261 int addRule(const Rule& value);
262
263 /// Add each rule in the specified `rules` to this rule set. Return the number of rules added.
264 ///
265 /// \note Note that a rule in `rules` will be
266 /// ignored if there is an existing rule having the same value or if
267 /// the number of rules in the set has reached the upper limit. Also
268 /// note that if not all valid rules will fit, the (possibly empty)
269 /// subset of unique values that will be added is implementation
270 /// dependent.
271 int addRules(const RuleSet& rules);
272
273 /// Remove from this rule set the rule having the specified `id`.
274 /// Return the number of rules removed (i.e., 1 on success and 0 if
275 /// there is no rule whose id is `id`).
276 ///
277 /// \pre The behavior is undefined unless `0 <= id < e_MAX_NUM_RULES`.
278 int removeRuleById(int id);
279
280 /// Remove the rule having the specified `value` from this rule set.
281 /// Return the number of rules removed (i.e., 1 on success and 0 if
282 /// there is no such a rule).
283 int removeRule(const Rule& value);
284
285 /// Remove each rule in the specified `rules` from this rule set.
286 /// Return the number of rules removed.
287 int removeRules(const RuleSet& rules);
288
289 /// Remove every rule in the rule set maintained by this object.
291
292 /// Assign to this object the value of the specified `rhs` object.
294
295 // ACCESSORS
296
297 /// Return the id of the rule having the specified `value` if such a rule exists, and a negative value otherwise.
298 ///
299 /// \note Note that if there are
300 /// multiple rules having `value`, the id of the first one found will be
301 /// returned and the order in which rules are searched is implementation
302 /// dependent.
303 int ruleId(const Rule& value) const;
304
305 /// Return the address of the rule having the specified `id` if such a rule exists, and 0 otherwise.
306 ///
307 /// \pre The behavior is undefined unless `0 <= id < maxNumRules()`.
308 ///
309 /// \note Note that rules may be assigned
310 /// non-sequential identifiers, and that there may be a valid rule whose
311 /// identifier is greater than `numRules()` (i.e., valid rules may
312 /// appear anywhere in the range `0 <= id < maxNumRules()`).
313 const Rule *getRuleById(int id) const;
314
315 /// Return the number of unique rules maintained in this `RuleSet` object.
316 ///
317 /// \note Note that this value is *not* the maximum identifier for
318 /// the rules currently in this container.
319 int numRules() const;
320
321 /// Return the total number of predicates in all rules maintained by
322 /// this object.
323 int numPredicates() const;
324
325 /// Format this object to the specified output `stream` at the
326 /// (absolute value of) the optionally specified indentation `level`
327 /// and return a reference to `stream`. If `level` is specified,
328 /// optionally specify `spacesPerLevel`, the number of spaces per
329 /// indentation level for this and all of its nested objects. If
330 /// `level` is negative, suppress indentation of the first line. If
331 /// `spacesPerLevel` is negative, format the entire output on one line,
332 /// suppressing all but the initial indentation (as governed by
333 /// `level`). If `stream` is not valid on entry, this operation has no
334 /// effect.
335 bsl::ostream& print(bsl::ostream& stream,
336 int level = 0,
337 int spacesPerLevel = 4) const;
338};
339
340// FREE OPERATORS
341
342/// Return `true` if the specified `lhs` and `rhs` rule sets have the same
343/// value, and `false` otherwise. Two rule sets have the same value if
344/// every rule that exists in one rule set also exists in the other.
345bool operator==(const RuleSet& lhs, const RuleSet& rhs);
346
347/// Return `true` if the specified `lhs` and `rhs` rule sets do not have the
348/// same value, and `false` otherwise. Two rule sets do not have the same
349/// value if there is at least one rule that exists in one rule but does not
350/// exist in the other.
351bool operator!=(const RuleSet& lhs, const RuleSet& rhs);
352
353/// Write the value of the specified `rules` to the specified `output`
354/// stream. Return the specified `output` stream
355bsl::ostream& operator<<(bsl::ostream& output, const RuleSet& rules);
356
357// ============================================================================
358// INLINE DEFINITIONS
359// ============================================================================
360
361 // -------------
362 // class RuleSet
363 // -------------
364
365// CLASS METHODS
366inline
368{
369 return e_MAX_NUM_RULES;
370}
371
372// ACCESSORS
373inline
374const Rule *RuleSet::getRuleById(int id) const
375{
376 return d_ruleAddresses[id];
377}
378
379inline
381{
382 return static_cast<int>(d_ruleHashtable.size());
383}
384
385inline
387{
388 return d_numPredicates;
389}
390
391} // close package namespace
392
393inline
394bsl::ostream& ball::operator<<(bsl::ostream& output, const RuleSet& rules)
395{
396 return rules.print(output, 0, -1);
397}
398
399
400
401#endif
402
403// ----------------------------------------------------------------------------
404// Copyright 2015 Bloomberg Finance L.P.
405//
406// Licensed under the Apache License, Version 2.0 (the "License");
407// you may not use this file except in compliance with the License.
408// You may obtain a copy of the License at
409//
410// http://www.apache.org/licenses/LICENSE-2.0
411//
412// Unless required by applicable law or agreed to in writing, software
413// distributed under the License is distributed on an "AS IS" BASIS,
414// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
415// See the License for the specific language governing permissions and
416// limitations under the License.
417// ----------------------------- END-OF-FILE ----------------------------------
418
419/** @} */
420/** @} */
421/** @} */
Definition ball_ruleset.h:151
static int maxNumRules()
Definition ball_ruleset.h:367
friend bool operator!=(const RuleSet &, const RuleSet &)
int removeRuleById(int id)
static void printMask(bsl::ostream &stream, MaskType mask, int level=0, int spacesPerLevel=0)
RuleSet(const RuleSet &original, bslma::Allocator *basicAllocator=0)
const Rule * getRuleById(int id) const
Definition ball_ruleset.h:374
int addRule(const Rule &value)
int ruleId(const Rule &value) const
int numPredicates() const
Definition ball_ruleset.h:386
friend bool operator==(const RuleSet &, const RuleSet &)
int addRules(const RuleSet &rules)
friend bsl::ostream & operator<<(bsl::ostream &, const RuleSet &)
RuleSet(bslma::Allocator *basicAllocator=0)
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
BSLMF_NESTED_TRAIT_DECLARATION(RuleSet, bslma::UsesBslmaAllocator)
@ BAEL_MAX_NUM_RULES
Definition ball_ruleset.h:165
@ e_MAX_NUM_RULES
Definition ball_ruleset.h:161
@ MAX_NUM_RULES
Definition ball_ruleset.h:166
RuleSet & operator=(const RuleSet &rhs)
Assign to this object the value of the specified rhs object.
int removeRules(const RuleSet &rules)
void removeAllRules()
Remove every rule in the rule set maintained by this object.
int removeRule(const Rule &value)
unsigned int MaskType
Definition ball_ruleset.h:158
int numRules() const
Definition ball_ruleset.h:380
~RuleSet()=default
Destroy this object.
Definition ball_rule.h:177
static int hash(const Rule &rule, int size)
Definition bslstl_unorderedset.h:733
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this set.
Definition bslstl_unorderedset.h:2927
Definition bslstl_vector.h:1120
Definition bslma_allocator.h:545
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition ball_administration.h:214
bsl::ostream & operator<<(bsl::ostream &output, const Attribute &attribute)
Definition bslma_usesbslmaallocator.h:344