Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component ball_categorymanager
[Package ball]

Provide a manager of named categories each having "thresholds". More...

Namespaces

namespace  ball

Detailed Description

Outline
Purpose:
Provide a manager of named categories each having "thresholds".
Classes:
ball::CategoryManager manager of category registry
See also:
Component ball_category, Component ball_loggermanager, Component ball_loggercategoryutil
Description:
This component provides a registry for category information and functions to manage the registry and its members. By "category" we mean a named entity that identifies a region or functional area of a program. A category name can be an arbitrary string, including the empty string. Note that category names are case-sensitive.
Associated with each category, besides its name, are four threshold levels known as "record", "pass", "trigger", and "trigger-all". Threshold levels are values in the range [0 .. 255]. (See the ball_loggermanager component-level documentation for a typical interpretation of these four thresholds.)
A category is represented by a ball::Category object. Although instances of ball::Category can be created directly, within the BALL logging framework they are generally created by the ball::CategoryManager class. ball::CategoryManager manages a registry of categories and exposes methods to add new categories to the registry (addCategory) and modify the threshold levels of existing categories (setThresholdLevels). ball::Category provides accessors for direct access to the name and threshold levels of a given category, and a single manipulator to set the four threshold levels levels (see ball_category).
Thread Safety:
ball::CategoryManager is thread-safe, meaning that any operation on the same instance can be safely invoked from any thread concurrently with any other operation.
Usage:
The code fragments in the following example illustrate some basic operations of category management including (1) adding categories to the registry, (2) accessing and modifying the threshold levels of existing categories, and (3) iterating over the categories in the registry.
First we define some hypothetical category names:
    const char *myCategories[] = {
        "EQUITY.MARKET.NYSE",
        "EQUITY.MARKET.NASDAQ",
        "EQUITY.GRAPHICS.MATH.FACTORIAL",
        "EQUITY.GRAPHICS.MATH.ACKERMANN"
    };
Next we create a ball::CategoryManager named manager and use the addCategory method to define a category for each of the names in myCategories. The threshold levels of each of the categories are set to slightly different values to help distinguish them when they are displayed later:
    ball::CategoryManager manager;

    const int NUM_CATEGORIES = sizeof myCategories / sizeof *myCategories;
    for (int i = 0; i < NUM_CATEGORIES; ++i) {
        manager.addCategory(myCategories[i],
                            192 + i, 96 + i, 64 + i, 32 + i);
    }
In the following, each of the new categories is accessed from the registry and their names and threshold levels printed:
    for (int i = 0; i < NUM_CATEGORIES; ++i) {
        const ball::Category *category =
                                     manager.lookupCategory(myCategories[i]);
        bsl::cout << "[ " << myCategories[i]
                  << ", " << category->recordLevel()
                  << ", " << category->passLevel()
                  << ", " << category->triggerLevel()
                  << ", " << category->triggerAllLevel()
                  << " ]" << bsl::endl;
    }
The following is printed to stdout:
    [ EQUITY.MARKET.NYSE, 192, 96, 64, 32 ]
    [ EQUITY.MARKET.NASDAQ, 193, 97, 65, 33 ]
    [ EQUITY.GRAPHICS.MATH.FACTORIAL, 194, 98, 66, 34 ]
    [ EQUITY.GRAPHICS.MATH.ACKERMANN, 195, 99, 67, 35 ]
We next use the setLevels method of ball::Category to adjust the threshold levels of our categories. The following also demonstrates use of the recordLevel, etc., accessors of ball::Category:
    for (int i = 0; i < NUM_CATEGORIES; ++i) {
        ball::Category *category = manager.lookupCategory(myCategories[i]);
        category->setLevels(category->recordLevel() + 1,
                            category->passLevel() + 1,
                            category->triggerLevel() + 1,
                            category->triggerAllLevel() + 1);
    }
Repeating the second for loop from above generates the following output on stdout:
    [ EQUITY.MARKET.NYSE, 193, 97, 65, 33 ]
    [ EQUITY.MARKET.NASDAQ, 194, 98, 66, 34 ]
    [ EQUITY.GRAPHICS.MATH.FACTORIAL, 195, 99, 67, 35 ]
    [ EQUITY.GRAPHICS.MATH.ACKERMANN, 196, 100, 68, 36 ]
Next we illustrate use of the index operator as a means of iterating over the registry of categories. In particular, we illustrate an alternate approach to modifying the threshold levels of our categories by iterating over the categories in the registry of manager to increment their threshold levels a second time:
    for (int i = 0; i < manager.length(); ++i) {
        ball::Category& category = manager[i];
        category.setLevels(category.recordLevel() + 1,
                           category.passLevel() + 1,
                           category.triggerLevel() + 1,
                           category.triggerAllLevel() + 1);
    }
Finally, we iterate over the categories in the registry to print them out one last time:
    for (int i = 0; i < manager.length(); ++i) {
        const ball::Category& category = manager[i];
        bsl::cout << "[ " << category.categoryName()
                  << ", " << category.recordLevel()
                  << ", " << category.passLevel()
                  << ", " << category.triggerLevel()
                  << ", " << category.triggerAllLevel()
                  << " ]" << bsl::endl;
    }
This iteration produces the following output on stdout:
    [ EQUITY.MARKET.NYSE, 194, 98, 66, 34 ]
    [ EQUITY.MARKET.NASDAQ, 195, 99, 67, 35 ]
    [ EQUITY.GRAPHICS.MATH.FACTORIAL, 196, 100, 68, 36 ]
    [ EQUITY.GRAPHICS.MATH.ACKERMANN, 197, 101, 69, 37 ]