A Sample C++ Applications

This appendix provides the sample code for the console, contacts, and hellogrid C++ examples.

A.1 Sample Code for the console Example

Now that you've run the console example, you are encouraged to have a look at the code. Each sample has a corresponding directory under examples which contains its sample specific source. There is also a common directory which contains source used in all samples.

Example A-1 illustrates the source code for the console.cpp command line application that enables you to interact with the cache using simple commands.

Example A-1 Code for the Console Sample Application

#include "coherence/lang.ns"

#include "coherence/io/pof/SystemPofContext.hpp"
#include "coherence/net/CacheFactory.hpp"
#include "coherence/net/NamedCache.hpp"
#include "coherence/util/Iterator.hpp"
#include "coherence/util/Map.hpp"
#include "coherence/util/Set.hpp"

#include "StreamParser.hpp"

#include <iostream>
#include <sstream>

using namespace coherence::lang;

using coherence::examples::StreamParser;
using coherence::io::pof::SystemPofContext;
using coherence::net::CacheFactory;
using coherence::net::NamedCache;
using coherence::util::Iterator;
using coherence::util::Map;
using coherence::util::Set;


/**
* This Coherence for C++ example provides a simple console for playing with
* caches from within C++.
*
* @argc  the number of command line arguments (including the process name)
* @argv  [cache-name]
*/
int main(int argc, char** argv)
    {
    NamedCache::Handle hCache;

    if (argc > 1)
        {
        // load command line specified cache
        try
            {
            hCache = CacheFactory::getCache(argv[1]);
            }
        catch (const std::exception& e)
            {
            std::cerr << e.what() << std::endl;
            }
        }

    while (true)
        {
        try
            {
            // prompt for input
            std::cout << "\nMap (";
            if (NULL == hCache)
                {
                std::cout << '?';
                }
            else
                {
                std::cout << hCache->getCacheName();
                }
            std::cout << "): " << std::flush;

            char achInput[256];
            std::cin.getline(achInput, 256);

            if (std::cin.fail())
                {
                std::cin.clear();
                continue;
                }

            std::stringstream ssInput(achInput);

            // process input
            String::View vsCmd = cast<String::View>(StreamParser::next(ssInput));

            if (vsCmd->equals("bye"))
                {
                // quit
                try
                    {
                    CacheFactory::shutdown();
                    }
                catch (const std::exception& e)
                    {
                    std::cerr << e.what() << std::endl;
                    return 1;
                    }
                return 0;
                }
            else if (vsCmd->equals("cache"))
                {
                // lookup a cache from the CacheFactory
                String::View vsCacheName = cast<String::View>(StreamParser::next(ssInput));
                hCache = CacheFactory::getCache(vsCacheName);
                }
            else if (vsCmd->equals("classes"))
                {
                // output the SystemClassLoader
                std::cout << SystemClassLoader::getInstance() << std::endl;
                }
            else if (vsCmd->equals("clear"))
                {
                // clear the current cache
                hCache->clear();
                }
            else if (vsCmd->equals("destroy"))
                {
                // destroy the current cache
                CacheFactory::destroyCache(hCache);
                }
            else if (vsCmd->equals("get"))
                {
                // perform a get operation on the current cache
                Object::View vKey   = StreamParser::next(ssInput);
                Object::View vValue = hCache->get(vKey);

                // print the current value
                std::cout << vValue << std::endl;
                }
            else if (vsCmd->equals("list"))
                {
                // obtain the entire cache contents
                Set::View vSetEntries = hCache->entrySet();

                // print key value pairs
                for (Iterator::Handle hIter = vSetEntries->iterator();
                        hIter->hasNext(); )
                    {
                    Map::Entry::View vEntry =
                        cast<Map::Entry::View>(hIter->next());

                    std::cout << vEntry->getKey() << " = "
                              << vEntry->getValue() << std::endl;
                    }
                }
            else if (vsCmd->equals("memory"))
                {
                // print information about allocated objects
                HeapAnalyzer::View vAnalyzer = System::getHeapAnalyzer();

                if (NULL == vAnalyzer)
                    {
                    std::cout << "analysis disabled" << std::endl;
                    }
                else if (cast<String::View>(StreamParser::next(ssInput))->
                        equals("delta"))
                    {
                    static HeapAnalyzer::Snapshot::View vMark;

                    // compare current against the heap mark
                    std::cout << (NULL == vMark
                            ? vAnalyzer->capture() : vAnalyzer->delta(vMark))
                            << std::endl;

                    // reset to mark based on the current heap useage
                    vMark = NULL;
                    vMark = vAnalyzer->capture();
                    }
                else
                    {
                    // output the current heap useage
                    std::cout << vAnalyzer << std::endl;
                    }
                }
            else if (vsCmd->equals("pof"))
                {
                // output the SystemPofContext
                std::cout << SystemPofContext::getInstance() << std::endl;
                }
            else if (vsCmd->equals("put"))
                {
                // perform a put operation on the current cache
                Object::View vKey   = StreamParser::next(ssInput);
                Object::View vValue = StreamParser::next(ssInput);
                Object::View vPrev  = hCache->put(vKey, vValue);

                // print the old value
                std::cout << vPrev << std::endl;
                }
            else if (vsCmd->equals("remove"))
                {
                // perform a remove operation on the current cache
                Object::View vKey  = StreamParser::next(ssInput);
                Object::View vPrev = hCache->remove(vKey);

                // print the removed value
                std::cout << vPrev << std::endl;
                }
            else if (vsCmd->equals("release"))
                {
                // release the current cache
                CacheFactory::releaseCache(hCache);
                }
            else if (vsCmd->equals("size"))
                {
                // print the size of the current cache
                size32_t cElements = hCache->size();

                std::cout << cElements << std::endl;
                }
            else if (vsCmd->equals("threads"))
                {
                // print a stack trace for all threads related to coherence
                Thread::dumpStacks(std::cout);
                }
            else if (vsCmd->equals(""))
                {
                continue;
                }
            else if (vsCmd->equals("help"))
                {
                // print help
                std::cout << "The commands are:"
                    << std::endl << "  bye"
                    << std::endl << "  cache <name>"
                    << std::endl << "  classes"
                    << std::endl << "  clear"
                    << std::endl << "  destroy"
                    << std::endl << "  get <key>"
                    << std::endl << "  help"
                    << std::endl << "  list"
                    << std::endl << "  memory [delta]"
                    << std::endl << "  pof"
                    << std::endl << "  put <key> <value>"
                    << std::endl << "  release"
                    << std::endl << "  remove <key>"
                    << std::endl << "  size"
                    << std::endl << "  threads"
                    << std::endl;
                }
            else
                {
                std::cout << "Unknown command: \"" << vsCmd << "\"\n"
                    << "Entry \"help\" for command list" << std::endl;
                }
            }
        catch (const NullPointerException::Throwable& e)
            {
            if (NULL == hCache)
                {
                std::cerr << "Please specify a cache using the \"cache\" "
                          << "command." << std::endl;
                }
            else
                {
                std::cerr << e << std::endl;
                }
            }
        catch (const std::exception& e)
            {
            std::cerr << "Error: " << e.what() << std::endl;
            }
        }
    }

A.2 Sample Code for the contacts Example

Now that you've run the contacts example, you are encouraged to have a look at the code. Each sample has a corresponding directory under examples which contains its sample specific source. There is also a common directory which contains source used in all samples.

Example A-2 illustrates the source code for the contacts example, and demonstrates how to store pre-existing (that is, non-Coherence) C++ classes in the grid.

A.2.1 ContactInfo.hpp

Example A-2 Header Code for the ContactInfo Sample Application

#ifndef COH_EXAMPLES_CONTACT_INFO_HPP
#define COH_EXAMPLES_CONTACT_INFO_HPP

#include <ostream>
#include <string>

/**
* The ContactInfo class encapsulates common contact information for a person.
*
* This serves as an example data object which does not have direct knowledge
* of Coherence but can be stored in the data grid.
*/
class ContactInfo
    {
    // ----- constructors ---------------------------------------------------

    public:
        /**
        * Create a new ContactInfo object.
        *
        * @param sName    the name of the person
        * @param sStreet  the street on which the person lives
        * @param sCity    the city where the person lives
        * @param sState   the state where the person lives
        * @param sZip     the zip code of the city where the person lives
        */
        ContactInfo(const std::string& sName,
                const std::string& sStreet, const std::string& sCity,
                const std::string& sState, const std::string& sZip);

        /**
        * Copy constructor.
        */
        ContactInfo(const ContactInfo& that);

    protected:
        /**
        * Default constructor.
        */
        ContactInfo();


    // ----- accessors ------------------------------------------------------

    public:
        /**
        * Determine the name of the person for which this ContactInfo object
        * contains contact information.
        *
        * @return the person's name
        */
        std::string getName() const;

        /**
        * Configure the name of the person for which this ContactInfo object
        * contains contact information.
        *
        * @param sName  the person's name
        */
        void setName(const std::string& sName);

        /**
        * Determine the street on which the person lives.
        *
        * @return the street name
        */
        std::string getStreet() const;

        /**
        * Configure the street on which the person lives.
        *
        * @param sStreet  the street name
        */
        void setStreet(const std::string& sStreet);

        /**
        * Determine the city in which the person lives.
        *
        * @return the city name
        */
        std::string getCity() const;

        /**
        * Configure the city in which the person lives.
        *
        * @param sCity  the city name
        */
        void setCity(const std::string& sCity);

        /**
        * Determine the state in which the person lives.
        *
        * @return the state name
        */
        std::string getState() const;

        /**
        * Configure the state in which the person lives.
        *
        * @param sState  the state name
        */
        void setState(const std::string& sState);

        /**
        * Determine the zip code of the city in which the person lives.
        *
        * @return the zip code
        */
        std::string getZip() const;

        /**
        * Configure the zip code of the city in which the person lives.
        *
        * @param sZip  the city's zip code
        */
        void setZip(const std::string& sZip);


    // ----- operators ------------------------------------------------------

    public:
        /**
        * Compare two ContactInfo objects for equality
        *
        * @param that  the ContactInfo to compare against
        *
        * @return true if this referenced contact is equal to this contact
        */
        bool operator==(const ContactInfo& that) const;


    // ----- data members ---------------------------------------------------

    private:
        /**
        * The person's name.
        */
        std::string m_sName;

        /**
        * The street on which the person lives.
        */
        std::string m_sStreet;

        /**
        * The city in which the person lives.
        */
        std::string m_sCity;

        /**
        * The state in which the person lives.
        */
        std::string m_sState;

        /**
        * The zip code of the city in which the person lives.
        */
        std::string m_sZip;
    };

/**
* Output this ContactInfo to the stream
*
* @param out  the stream to output to
*
* @return the stream
*/
std::ostream& operator<<(std::ostream& out, const ContactInfo& info);

#endif // COH_EXAMPLES_CONTACT_INFO_HPP

A.2.2 ContactInfo.cpp

Example A-3 C++ Code for the ContactInfo Sample Application

#include "ContactInfo.hpp"


// ----- constructors -------------------------------------------------------

ContactInfo::ContactInfo(const std::string& sName,
        const std::string& sStreet, const std::string& sCity,
        const std::string& sState, const std::string& sZip)
    {
    setName(sName);
    setStreet(sStreet);
    setCity(sCity);
    setState(sState);
    setZip(sZip);
    }

ContactInfo::ContactInfo(const ContactInfo& that)
    {
    setName(that.getName());
    setStreet(that.getStreet());
    setCity(that.getCity());
    setState(that.getState());
    setZip(that.getZip());
    }

ContactInfo::ContactInfo()
    {
    }

// ----- accessors ----------------------------------------------------------

std::string ContactInfo::getName() const
    {
    return m_sName;
    }

void ContactInfo::setName(const std::string& sName)
    {
    m_sName = sName;
    }

std::string ContactInfo::getStreet() const
    {
    return m_sStreet;
    }

void ContactInfo::setStreet(const std::string& sStreet)
    {
    m_sStreet = sStreet;
    }

std::string ContactInfo::getCity() const
    {
    return m_sCity;
    }

void ContactInfo::setCity(const std::string& sCity)
    {
    m_sCity = sCity;
    }

std::string ContactInfo::getState() const
    {
    return m_sState;
    }

void ContactInfo::setState(const std::string& sState)
    {
    m_sState = sState;
    }

std::string ContactInfo::getZip() const
    {
    return m_sZip;
    }

void ContactInfo::setZip(const std::string& sZip)
    {
    m_sZip = sZip;
    }


// ----- operators ----------------------------------------------------------

bool ContactInfo::operator==(const ContactInfo& that) const
    {
    return getName()   == that.getName()   &&
           getStreet() == that.getStreet() &&
           getCity()   == that.getCity()   &&
           getState()  == that.getState()  &&
           getZip()    == that.getZip();
    }

std::ostream& operator<<(std::ostream& out, const ContactInfo& info)
    {
    out << "ContactInfo("
            << "Name="     << info.getName()
            << ", Street=" << info.getStreet()
            << ", City="   << info.getCity()
            << ", State="  << info.getState()
            << ", Zip="    << info.getZip()
            << ')';
    return out;
    }

A.2.3 PortableContactInfo.hpp

Example A-4 Header Code for the PortableContactInfo Applications

#ifndef COH_EXAMPLES_PORTABLE_CONTACT_INFO_HPP
#define COH_EXAMPLES_PORTABLE_CONTACT_INFO_HPP

// This set of functions add support for storing ContactInfo objects in
// Coherence without introducing knowledge of Coherence to the ContactInfo
// class.  This portable version of ClassInfo can be referred to as
// Portable<ContactInfo>

#include "ContactInfo.hpp"

#include "coherence/io/pof/PofWriter.hpp"
#include "coherence/io/pof/PofReader.hpp"
#include "coherence/io/pof/Portable.hpp"

/**
* The POF type id for Portable<ContactInfo>
*/
#define POF_CONTACT_INFO_ID 1001

/**
* Serialize a ContactInfo object to a POF stream.
*
* @param info  the ContactInfo to seralize
* @param hOut  the PofWritter to write to
*/
void serialize(const ContactInfo& info, coherence::io::pof::PofWriter::Handle hOut);

/**
* Deserialize a ContactInfo object from a POF stream.
*
* @param info  the ContactInfo to seralize
* @param hIn   the PofReader to read from
*/
void deserialize(ContactInfo& info, coherence::io::pof::PofReader::Handle hIn);

/**
* Return a hashcode code for a ContactInfo object.
*/
coherence::lang::size32_t hash(const ContactInfo& info);

#endif // COH_EXAMPLES_PORTABLE_CONTACT_INFO_HPP

A.2.4 PortableContactInfo.cpp

Example A-5 C++ Code for the PortableContactInfo Application

#include "PortableContactInfo.hpp"

#include "coherence/lang.ns"

#include "coherence/io/pof/PofWriter.hpp"
#include "coherence/io/pof/PofReader.hpp"
#include "coherence/io/pof/Portable.hpp"
#include "coherence/io/pof/SystemPofContext.hpp"

using namespace coherence::lang;


// register Portable<ContactInfo> with the SystemPofContext
COH_REGISTER_PORTABLE_CLASS(POF_CONTACT_INFO_ID, coherence::io::pof::Portable<ContactInfo>);

void serialize(const ContactInfo& info, coherence::io::pof::PofWriter::Handle hOut)
    {
    hOut->writeString(0, info.getName());
    hOut->writeString(1, info.getStreet());
    hOut->writeString(2, info.getCity());
    hOut->writeString(3, info.getState());
    hOut->writeString(4, info.getZip());
    }

void deserialize(ContactInfo& info, coherence::io::pof::PofReader::Handle hIn)
    {
    info.setName  (hIn->readString(0));
    info.setStreet(hIn->readString(1));
    info.setCity  (hIn->readString(2));
    info.setState (hIn->readString(3));
    info.setZip   (hIn->readString(4));
    }

size32_t hash(const ContactInfo& info)
    {
    // ContactInfo is not used as a key, use identity hash
    return size32_t(size_t(&info));
    }

A.2.5 contacts.cpp

Example A-6 Code for the ContactInfo Data Object

#include "coherence/lang.ns"

#include "coherence/io/pof/Portable.hpp"
#include "coherence/net/CacheFactory.hpp"
#include "coherence/net/NamedCache.hpp"

#include "ContactInfo.hpp"
#include "PortableContactInfo.hpp"
#include "StreamParser.hpp"

#include <iostream>
#include <sstream>

using namespace coherence::lang;

using coherence::examples::StreamParser;
using coherence::io::pof::Portable;
using coherence::net::CacheFactory;
using coherence::net::NamedCache;

// ----- prototypes ---------------------------------------------------------

/**
* Create a contact from stdin.
*
* @return the contact
*/
ContactInfo readContact();

/**
* This Coherence for C++ example illustrates how to use non-Coherence data
* objects in the grid. This example operates on the ContactInfo class which
* is not Coherence aware.
*
* To run this against a remote cache, the proxy node must have the
* corresponding Java ContactInfo.class in its classpath.
*
* @argc  the number of command line arguments (including the process name)
* @argv  [cache-name]
*/
int main(int argc, char** argv)
    {
    try
        {
        String::View       vsCacheName = argc > 1 ? argv[1] : "dist-contacts";
        NamedCache::Handle hCache      = CacheFactory::getCache(vsCacheName);

        while (true)
            {
            // prompt for input
            std::cout << "contacts> " << std::flush;

            char achInput[256];
            std::cin.getline(achInput, 256);
            std::stringstream ssInput(achInput);

            // process input
            String::View vsCmd = cast<String::View>(
                    StreamParser::next(ssInput));

            if (vsCmd->equals("bye"))
                {
                // quit
                CacheFactory::shutdown();
                return 0;
                }
            else if (vsCmd->equals("create"))
                {
                ContactInfo ci = readContact();
                std::cout << "storing: " << ci << std::endl;
                hCache->put(String::create(ci.getName().c_str()),
                        Portable<ContactInfo>::create(ci));
                }
            else if (vsCmd->equals("find"))
                {
                String::View vsPart = cast<String::View>(
                        StreamParser::next(ssInput));

                std::cout << "Name: " << std::flush;
                std::cin.getline(achInput, 256);
                String::View vsName = achInput;

                Portable<ContactInfo>::View vInfo =
                    cast<Portable<ContactInfo>::View>(hCache->get(vsName));

                if (NULL == vInfo)
                    {
                    std::cout << vsName << " not found" << std::endl;
                    continue;
                    }

                if (vsPart->equals("all") || vsPart->equals(""))
                    {
                    std::cout << vInfo << std::endl;
                    }
                else if (vsPart->equals("street"))
                    {
                    std::cout << vInfo->getStreet() << std::endl;
                    }
                else if (vsPart->equals("city"))
                    {
                    std::cout << vInfo->getCity() << std::endl;
                    }
                else if (vsPart->equals("state"))
                    {
                    std::cout << vInfo->getState() << std::endl;
                    }
                else if (vsPart->equals("zip"))
                    {
                    std::cout << vInfo->getZip() << std::endl;
                    }
                else
                    {
                    std::cerr << "find must be followed by, street, city, "
                        << "state, or zip" << std::endl;
                    }
                }
            else // output help
                {
                std::cout << "commands are:"
                    << std::endl << "bye"
                    << std::endl << "create"
                    << std::endl << "find <street | city | state | zip | all>"
                    << std::endl;
                }
            }
        }
    catch (const std::exception& e)
        {
        std::cerr << e.what() << std::endl;
        }
    }

ContactInfo readContact()
    {
    char achInput[256];
    std::cout << "Name: " << std::flush;
    std::cin.getline(achInput, 256);
    std::string sName(achInput);

    std::cout << "Street: " << std::flush;
    std::cin.getline(achInput, 256);
    std::string sStreet(achInput);

    std::cout << "City: " << std::flush;
    std::cin.getline(achInput, 256);
    std::string sCity(achInput);

    std::cout << "State: " << std::flush;
    std::cin.getline(achInput, 256);
    std::string sState(achInput);

    std::cout << "Zip: " << std::flush;
    std::cin.getline(achInput, 256);
    std::string sZip(achInput);

    return ContactInfo(sName, sStreet, sCity, sState, sZip);
    }

A.3 Sample Code for the hellogrid Example

Now that you've run the hellogrid samples, you are encouraged to have a look at the code. Each sample has a corresponding directory under examples which contains its sample specific source. There is also a common directory which contains source used in all samples.

Example A-7 illustrates the source code for the hellogrid.cpp example, and demonstrates basic cache access.

Example A-7 Code for the HelloGrid Sample Application

#include "coherence/lang.ns"

#include "coherence/net/CacheFactory.hpp"
#include "coherence/net/NamedCache.hpp"
#include "coherence/stl/boxing_map.hpp"
#include "coherence/util/aggregator/ComparableMin.hpp"
#include "coherence/util/extractor/IdentityExtractor.hpp"
#include "coherence/util/filter/GreaterFilter.hpp"
#include "coherence/util/processor/NumberIncrementor.hpp"
#include "coherence/util/Iterator.hpp"
#include "coherence/util/Filter.hpp"
#include "coherence/util/Set.hpp"
#include "coherence/util/ValueExtractor.hpp"
#include "coherence/util/ValueManipulator.hpp"

#include <iostream>

using namespace coherence::lang;

using coherence::net::CacheFactory;
using coherence::net::NamedCache;
using coherence::stl::boxing_map;
using coherence::util::aggregator::ComparableMin;
using coherence::util::extractor::IdentityExtractor;
using coherence::util::filter::GreaterFilter;
using coherence::util::processor::NumberIncrementor;
using coherence::util::Iterator;
using coherence::util::Filter;
using coherence::util::Set;
using coherence::util::ValueExtractor;
using coherence::util::ValueManipulator;


/**
* This example demonstrates the basics of accessing a cache by using the
* Coherence C++ API.
*
* @argc  the number of command line arguments (including the process name)
* @argv  [cache-name]
*/
int main(int argc, char** argv)
    {
    try
        {

A.3.1 Basic Cache Access

// read optional cache name from command line
        String::View vsCacheName = argc > 1 ? argv[1] : "dist-hello";

        // retrieve the named cache
        NamedCache::Handle hCache = CacheFactory::getCache(vsCacheName);
        std::cout << "retrieved cache \"" << hCache->getCacheName()
                  << "\" containing " << hCache->size() << " entries"
                  << std::endl;

        // create a key, and value
        String::View vsKey   = "hello";
        String::View vsValue = "grid";

        // insert the pair into the cache
        hCache->put(vsKey, vsValue);
        std::cout << "\tput: " << vsKey << " = " << vsValue << std::endl;

        // read back the value, casting to the expected value type
        String::View vsGet = cast<String::View>(hCache->get(vsKey));
        std::cout << "\tget: " << vsKey << " = " << vsGet << std::endl;

        // read a non-existent entry from the cache; result will be NULL
        String::View vsKeyDummy = "dummy";
        Object::View vDummy     = hCache->get(vsKeyDummy);
        std::cout << "\tget: " << vsKeyDummy << " = " << vDummy << std::endl;

        // work with non-string data types
        hCache->put(Integer32::valueOf(12345), Float64::valueOf(6.7));
        hCache->put(Integer32::valueOf(23456), Float64::valueOf(7.8));
        hCache->put(Integer32::valueOf(34567), Float64::valueOf(8.9));

        // iterate and print the cache contents, treating contents abstractly
        std::cout << "entire cache contents:" << std::endl;
        for (Iterator::Handle hIter = hCache->entrySet()->iterator();
             hIter->hasNext(); )
            {
            Map::Entry::View vEntry = cast<Map::Entry::View>(hIter->next());
            Object::View     vKey   = vEntry->getKey();
            Object::View     vValue = vEntry->getValue();
            std::cout << '\t' << vKey << " = " << vValue << std::endl;
            }

        // remove strings to make the cache contents uniform
        hCache->remove(vsKey);

A.3.2 STL-like Map Adapter

// caches may also be wrapped with an STL-like map adapter
        typedef boxing_map<Integer32, Float64> float_cache;
        float_cache cache(hCache);
        cache[45678] = 9.1;
        std::cout << "updated cache contents:" << std::endl;
        for (float_cache::iterator i = cache.begin(), e = cache.end(); i != e; ++i)
            {
            std::cout << '\t' << i->first << " = " << i->second << std::endl;
            }

A.3.3 InvocableMap Aggregation

// perform aggregation, and print the results
        ValueExtractor::View vExtractor = IdentityExtractor::getInstance();
        Float64::View        vFlMin     = cast<Float64::View>(
                hCache->aggregate((Filter::View) NULL,
                ComparableMin::create(vExtractor)));
        std::cout << "minimum: " << vFlMin << std::endl;

A.3.4 Query the Cache

// query the cache, and print the results
        Filter::View vFilter    = GreaterFilter::create(vExtractor,
                                                  Float64::valueOf(7.0));
        Set::View    vSetResult = hCache->entrySet(vFilter);

        std::cout << "filtered cache contents by " << vFilter << std::endl;
        for (Iterator::Handle hIter = vSetResult->iterator(); hIter->hasNext(); )
            {
            Map::Entry::View vEntry = cast<Map::Entry::View>(hIter->next());
            Object::View     vKey   = vEntry->getKey();
            Object::View     vValue = vEntry->getValue();
            std::cout << '\t' << vKey << " = " << vValue << std::endl;
            }

A.3.5 Continuous Query Cache

// present a real-time filtered view of the cache
        NamedCache::Handle hCacheCqc =
            ContinuousQueryCache::create(hCache, vFilter);
        std::cout << "ContinuousQueryCache filtered view: " << std::endl;
        for (Iterator::Handle hIter = hCacheCqc->entrySet()->iterator();
             hIter->hasNext(); )
            {
            Map::Entry::View vEntry = cast<Map::Entry::View>(hIter->next());
            Object::View     vKey   = vEntry->getKey();
            Object::View     vValue = vEntry->getValue();
            std::cout << '\t' << vKey << " = " << vValue << std::endl;
            }

        // register MapListener to print changes to stdout
        std::cout << "start listening to events..." << std::endl;
        hCache->addFilterListener(VerboseMapListener::create());

A.3.6 InvocableMap Invoke All

// invoke entry processor on matching cache contents, incrementing each value 
        Float64::Handle vFlIncr = Float64::valueOf(1.0);
        std::cout << "increment results by " << vFlIncr << std::endl;
        hCacheCqc->invokeAll((Filter::View) NULL, NumberIncrementor::create(
                (ValueManipulator::View) NULL, vFlIncr, /*fPost*/ true));

        // stop the CQC event queue thread and remove listeners
        hCacheCqc->release();
        // disconnect from the grid
        CacheFactory::shutdown();
        }
    catch (const std::exception& e)
        {
        std::cerr << "error: " << e.what() << std::endl;
        return 1;
        }
    return 0;
    }