[id='grouping-api_{context}']
= Grouping API

Complementary to the Key affinity service, the `Grouping` API allows you to co-locate a group of entries on the same nodes, but without being able to select the actual nodes.

By default, the segment of a key is computed using the key's `hashCode()`.
If you use the `Grouping` API, {brandname} will compute the segment of the group and use that as the segment of the key.

When the `Grouping` API is in use, it is important that every node can still compute the owners of every key without contacting other nodes.
For this reason, the group cannot be specified manually.
The group can either be intrinsic to the entry (generated by the key class) or extrinsic (generated by an external function).

To use the `Grouping` API, you must enable groups.

[source,java]
----
include::code_examples/EnableGroups.java[]
----

[source,xml,options="nowrap",subs=attributes+]
----
include::xml/enable_groups.xml[]
----

If you have control of the key class (you can alter the class definition, it's not part of an unmodifiable library), then we recommend using an intrinsic group.
The intrinsic group is specified by adding the `@Group` annotation to a method, for example:

[source,java]
----
include::code_examples/IntrinsicGroup.java[]
----

NOTE: The group method must return a `String`

If you don't have control over the key class, or the determination of the group is an orthogonal concern to the key class, we recommend using an extrinsic group.
An extrinsic group is specified by implementing the `Grouper` interface.

[source,java]
----
include::code_examples/ExtrinsicGroup.java[]
----

If multiple `Grouper` classes are configured for the same key type, all of them will be called, receiving the value computed by the previous one.
If the key class also has a `@Group` annotation, the first `Grouper` will receive the group computed by the annotated method.
This allows you even greater control over the group when using an intrinsic group.

.Example `Grouper` implementation
[source,java]
----
include::code_examples/GrouperImplementation.java[]
----

`Grouper` implementations must be registered explicitly in the cache configuration.
If you are configuring {brandname} programmatically:

[source,java]
----
include::code_examples/GrouperRegistration.java[]
----

Or, if you are using XML:

[source,xml,options="nowrap",subs=attributes+]
----
include::xml/grouper_registration.xml[]
----

[discrete]
== Advanced API

`AdvancedCache` has two group-specific methods:

* `link:{javadocroot}/org/infinispan/AdvancedCache.html#getGroup-java.lang.String-[getGroup(groupName)]` retrieves all keys in the cache that belong to a group.
* `link:{javadocroot}/org/infinispan/AdvancedCache.html#removeGroup-java.lang.String-[removeGroup(groupName)]` removes all the keys in the cache that belong to a group.

Both methods iterate over the entire data container and store (if present), so they can be slow when a cache contains lots of small groups.
