8 Understanding the Coherence for C++ API

The Coherence for C++ API allows C++ applications to access Coherence clustered services, including data, data events, and data processing from outside the Coherence cluster.

Documentation of the Coherence for C++ API is available in two locations. The Oracle Coherence C++ API Reference and also in the doc directory of the Coherence for C++ distribution.

The following sections are included in this chapter:

8.1 CacheFactory

CacheFactory provides several static methods for retrieving and releasing NamedCache instances:

  • NamedCache::Handle getCache(String::View vsName)—retrieves a NamedCache implementation that corresponds to the NamedCache with the specified name running within the remote Coherence cluster.

  • void releaseCache(NamedCache::Handle hCache)—releases all local resources associated with the specified instance of the cache. After a cache is released, it can no longer be used. The content of the cache, however, is not affected.

  • void destroyCache(NamedCache::Handle hCache)—destroys the specified cache across the Coherence cluster.

8.2 NamedCache

A NamedCache is a map of resources shared among members of a cluster. The NamedCache provides several methods used to retrieve the name of the cache and the service, and to release or destroy the cache:

  • String::View getCacheName()—returns the name of the cache as a String.

  • CacheService::Handle getCacheService()—returns a handle to the CacheService that this NamedCache is a part of.

  • bool isActive()—specifies whether this NamedCache is active.

  • void release()—releases the local resources associated with this instance of the NamedCache. The cache is no longer usable, but the cache contents are not affected.

  • void destroy()—releases and destroys this instance of the NamedCache.

NamedCache interface also extends the following interfaces: QueryMap, InvocableMap, ConcurrentMap, CacheMap and ObservableMap.

8.3 QueryMap

A QueryMap can be thought of as an extension of the Map class with additional query features. These features allow the ability to query a cache using various filters. Filters are described in "Filter".

  • Set::View keySet(Filter::View vFilter)—returns a set of the keys contained in this map for entries that satisfy the criteria expressed by the filter.

  • Set::View entrySet(Filter::View vFilter)—returns a set of the entries contained in this map that satisfy the criteria expressed by the filter. Each element in the returned set is a Map::Entry object.

  • Set::View entrySet(Filter::View vFilter, Comparator::View vComparator)—returns a set of the entries contained in this map that satisfy the criteria expressed by the filter. Each element in the returned set is a Map::Entry object. This version of entrySet further guarantees that its iterator traverses the set in ascending order based on the entry values which are sorted by the specified Comparator or according to the natural ordering.

Additionally, the QueryMap class includes the ability to add and remove indexes. Indexes are used to correlate values stored in the cache to their corresponding keys and can dramatically increase the performance of the keySet and entrySet methods.

  • void addIndex(ValueExtractor::View vExtractor, boolean_t fOrdered, Comparator::View vComparator)—adds an index to this QueryMap. The index correlates values stored in this indexed Map (or attributes of those values) to the corresponding keys in the indexed Map and increase the performance of keySet and entrySet methods.

  • void removeIndex(ValueExtractor::View vExtractor)—removes an index from this QueryMap.

See "Querying a Cache (C++)" for a more in depth look at queries. See also the C++ examples in "Simple Queries"

8.4 ObservableMap

An ObservableMap provides an application with the ability to listen for cache changes. Applications that implement ObservableMap can add key and filter listeners to receive events from any cache, regardless of whether that cache is local, partitioned, near, replicated, using read-through, write-through, write-behind, overflow, disk storage, and so on. ObservableMap also provides methods to remove these listeners.

  • void addKeyListener(MapListener::Handle hListener, Object::View vKey, bool fLite)—adds a map listener for a specific key.

  • void removeKeyListener(MapListener::Handle hListener, Object::View vKey)—removes a map listener that previously signed up for events about a specific key.

  • void addFilterListener(MapListener::Handle hListener, Filter::View vFilter = NULL, bool fLite = false)—adds a map listener that receives events based on a filter evaluation.

  • void removeFilterListener(MapListener::Handle hListener, Filter::View vFilter = NULL)—removes a map listener that previously signed up for events based on a filter evaluation.

See the C++ examples in "Signing Up for all Events".

8.5 InvocableMap

An InvocableMap is a cache against which both entry-targeted processing and aggregating operations can be invoked. The operations against the cache contents are executed by (and thus within the localized context of) a cache. This is particularly efficient in a distributed environment because it localizes processing: the processing of the cache contents are moved to the location at which the entries-to-be-processed are being managed. For more information about processors and aggregators, see "Entry Processors" and "Entry Aggregators".

  • Object::Holder invoke(Object::View vKey, EntryProcessor::Handle hAgent)—invokes the passed processor (EntryProcessor) against the entry (Entry) specified by the passed key, returning the result of the invocation.

  • Map::View invokeAll(Collection::View vCollKeys, EntryProcessor::Handle hAgent)—invokes the passed processor (EntryProcessor) against the entries (Entry objects) specified by the passed keys, returning the result of the invocation for each.

  • Map::View invokeAll(Filter::View vFilter, EntryProcessor::Handle hAgent)—invokes the passed processor (EntryProcessor) against the entries (Entry objects) that are selected by the given filter, returning the result of the invocation for each.

  • Object::Holder aggregate(Collection::View vCollKeys, EntryAggregator::Handle hAgent)—performs an aggregating operation against the entries specified by the passed keys.

  • Object::Holder aggregate(Filter::View vFilter, EntryAggregator::Handle hAgent)—performs an aggregating operation against the entries that are selected by the given filter.

8.6 Filter

Filter provides the ability to filter results and only return objects that meet a given set of criteria. All filters must implement Filter. Filters are commonly used with the QueryMap API to query the cache for entries that meet a given criteria. See also "QueryMap".

  • bool evaluate(Object::View v)—applies a test to the specified object and returns true if the test passes, false otherwise.

Coherence for C++ includes many concrete Filter implementations in the coherence::util::filter namespace. Below are several commonly used filters:

  • EqualsFilter is used to test for equality. To create an EqualsFilter to test that an object equals 5:

    Example 8-1 Using the EqualsFilter Method

    EqualsFilter::View vEqualsFilter = EqualsFilter::create(IdentityExtractor::getInstance(), Integer32::valueOf(5));
    
  • GreaterEqualsFilter is used to test a "Greater or Equals" condition. To create a GreaterEqualsFilter that tests that an objects value is >= 55:

    Example 8-2 Using the GreaterEqualsFilter Method

    GreaterEqualsFilter::View vGreaterEqualsFilter = GreaterEqualsFilter::create(IdentityExtractor::getInstance(), Integer32::valueOf(55));
    
  • LikeFilter is used for pattern matching. To create a LikeFilter that tests that the string representation of an object begins with "Belg":

    Example 8-3 Using the LikeFilter Method

    LikeFilter::View vLikeFilter = LikeFilter::create(IdentityExtractor::getInstance(), "Belg%");
    

    Some filters combine two filters to create a compound condition.

  • AndFilter is used to combine two filters to create an "AND" condition. To create an AndFilter that tests that an objects value is greater than 10 and less than 20:

    Example 8-4 Using the AndFilter Method

    AndFilter::View vAndFilter = AndFilter::create(
            GreaterFilter::create(IdentityExtractor::getInstance(), Integer32::valueOf(10)),
            LessFilter::create(IdentityExtractor::getInstance(), Integer32::valueOf(20)));
    
  • OrFilter is used to combine two filters to create an "OR" condition. To create an OrFilter that tests that an object's value is less than 10 or greater than 20:

    Example 8-5 Using the OrFilter Method

    OrFilter::View vOrFilter = OrFilter::create(
            LessFilter::create(IdentityExtractor::getInstance(), Integer32::valueOf(10)),
            GreaterFilter::create(IdentityExtractor::getInstance(), Integer32::valueOf(20)));
    

8.7 Value Extractors

A value extractor is used to extract values from an object and to provide an identity for the extraction. All extractors must implement ValueExtractor.

Note:

All concrete extractor implementations must also explicitly implement the hashCode and equals functions in a way that is based solely on the object's serializable state.
  • Object::Holder extract(Object::Holder ohTarget)—extracts the value from the passed object.

  • bool equals(Object::View v)—compares the ValueExtractor with another object to determine equality. Two ValueExtractor objects, ve1 and ve2 are considered equal if and only if ve1->extract(v) equals ve2->extract(v) for all values of v.

  • size32_t hashCode()—determine a hash value for the ValueExtractor object according to the general Object#hashCode() contract.

Coherence for C++ includes the following extractors:

  • ChainedExtractor—is a composite ValueExtractor implementation based on an array of extractors. The extractors in the array are applied sequentially left-to-right, so a result of a previous extractor serves as a target object for a next one.

  • ComparisonValueExtractor—returns a result of comparison between two values extracted from the same target.

  • IdentityExtractor—is a trivial implementation that does not actually extract anything from the passed value, but returns the value itself.

  • KeyExtractor—is a special purpose implementation that serves as an indicator that a query should be run against the key objects rather than the values.

  • MultiExtractor—is a composite ValueExtractor implementation based on an array of extractors. All extractors in the array are applied to the same target object and the result of the extraction is a List of extracted values.

  • ReflectionExtractor—extracts a value from a specified object property.

See the C++ examples in "Query Concepts".

8.8 Entry Processors

An entry processor is an agent that operates against the entry objects within a cache. All entry processors must implement EntryProcessor.

  • Object::Holder process(InvocableMap::Entry::Handle hEntry)—process the specified entry.

  • Map::View processAll(Set::View vSetEntries)—process a collection of entries.

Coherence for C++ includes several EntryProcessor implementations in the coherence::util::processor namespace.

See the hellogrid C++ example in Chapter 16, "Sample C++ Application."

8.9 Entry Aggregators

An entry aggregator represents processing that can be directed to occur against some subset of the entries in an InvocableMap, resulting in an aggregated result. Common examples of aggregation include functions such as minimum, maximum, sum, and average. However, the concept of aggregation applies to any process that must evaluate a group of entries to come up with a single answer. Aggregation is explicitly capable of being run in parallel, for example in a distributed environment.

All aggregators must implement the EntryAggregator interface:

  • Object::Holder aggregate(Collection::View vCollKeys)— processes a collection of entries to produce an aggregate result.

Coherence for C++ includes several EntryAggregator implementations in the coherence::util::aggregator namespace.

Note:

Like cached value objects, all custom Filter, ValueExtractor, EntryProcessor, and EntryAggregator implementation classes must be correctly registered in the POF context of the C++ application and cluster-side node to which the client is connected. As such, corresponding Java implementations of the custom C++ types must be created, compiled, and deployed on the cluster-side node. Note that the actual execution of these custom types is performed by the Java implementation and not the C++ implementation. See Chapter 10, "Building Integration Objects (C++)," for additional details.