18/37

# 9 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 online API documentation and also in the `doc` directory of the Coherence for C++ distribution.

## 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.

## 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`.

## 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 will traverse 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`. This enables you to correlate 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 "Query the Cache for C++ Clients" for a more in depth look at queries. See also the C++ examples in "Simple Queries"

## 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".

## 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.

## 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 9-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 9-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 9-3 Using the LikeFilter Method

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

  Some filters can be used to 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 9-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 9-5 Using the OrFilter Method

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

## 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".

## 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 17, "Sample Applications for C++ Clients."

## 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 the these custom types is performed by the Java implementation and not the C++ implementation. See Chapter 11, "Building Integration Objects for C++ Clients," for additional details.