Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.oracle.coherence.repository.AbstractAsyncRepository Maven / Gradle / Ivy
/*
* Copyright (c) 2021, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.oracle.coherence.repository;
import com.tangosol.net.AsyncNamedMap;
import com.tangosol.net.NamedMap;
import com.tangosol.util.Aggregators;
import com.tangosol.util.Filter;
import com.tangosol.util.Filters;
import com.tangosol.util.Fragment;
import com.tangosol.util.InvocableMap;
import com.tangosol.util.Processors;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.ValueUpdater;
import com.tangosol.util.comparator.ExtractorComparator;
import com.tangosol.util.function.Remote;
import com.tangosol.util.stream.RemoteCollector;
import com.tangosol.util.stream.RemoteCollectors;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.tangosol.util.function.Remote.Comparator.comparing;
import static com.tangosol.util.stream.RemoteCollectors.groupingBy;
/**
* Abstract base class for asynchronous Coherence
* repository
* implementations.
*
* @param the type of entity's identifier
* @param the type of entity stored in this repository
*
* @author Ryan Lubke 2021.04.08
* @author Aleks Seovic
* @since 21.06
*/
public abstract class AbstractAsyncRepository
extends AbstractRepositoryBase>
{
// ----- AbstractRepositoryBase methods ---------------------------------
@Override
NamedMap getNamedMap()
{
return getMap().getNamedMap();
}
// ----- CRUD support ---------------------------------------------------
/**
* Store the specified entity.
*
* @param entity the entity to store
*
* @return the saved entity
*/
public CompletableFuture save(T entity)
{
return getMapInternal().putAll(Collections.singletonMap(getId(entity), entity)).thenApply(unused -> entity);
}
/**
* Store all specified entities as a batch.
*
* @param colEntities the entities to store
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
*/
public CompletableFuture saveAll(Collection extends T> colEntities)
{
return saveAll(colEntities.stream());
}
/**
* Store all specified entities as a batch.
*
* @param strEntities the entities to store
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
*/
public CompletableFuture saveAll(Stream extends T> strEntities)
{
return getMapInternal().putAll(strEntities.collect(Collectors.toMap(this::getId, v -> v)));
}
/**
* Return an entity with a given identifier.
*
* @param id the entity's identifier
*
* @return a {@link CompletableFuture} for the value to which the specified
* {@code id} is mapped
*/
public CompletableFuture get(ID id)
{
return getMapInternal().get(id);
}
/**
* Returns true if this repository contains the entity with the specified identifier.
*
* @param id the identifier of an entity to check if it exists
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository contains the entity with the specified identifier
*/
public CompletableFuture exists(ID id)
{
return getMapInternal().containsKey(id);
}
/**
* Return the value extracted from an entity with a given identifier.
*
* For example, you could extract {@code Person}'s {@code name} attribute by
* calling a getter on a remote {@code Person} entity instance:
*
* people.get(ssn, Person::getName);
*
*
* You could also extract a {@link Fragment} containing the {@code Person}'s
* {@code name} and {@code age} attributes by calling corresponding getters
* on the remote {@code Person} entity instance:
*
* Fragment<Person> person = people.get(ssn, Extractors.fragment(Person::getName, Person::getAge));
* System.out.println("name: " + person.get(Person::getName));
* System.out.println(" age: " + person.get(Person::getAge));
*
*
* Finally, you can also extract nested fragments:
*
* Fragment<Person> person = people.get(ssn,
* Extractors.fragment(Person::getName, Person::getAge,
* Extractors.fragment(Person::getAddress, Address::getCity, Address::getState));
* System.out.println(" name: " + person.get(Person::getName));
* System.out.println(" age: " + person.get(Person::getAge));
*
* Fragment<Address> address = person.getFragment(Person::getAddress);
* System.out.println(" city: " + address.get(Address::getCity));
* System.out.println("state: " + address.get(Address::getState));
*
* Note that the actual extraction (via the invocation of the specified
* getter method) will happen on the primary owner for the specified entity,
* and only the extracted value will be sent over the network to the client,
* which can significantly reduce the amount of data transferred.
*
* @param id the entity's identifier
* @param extractor the {@link ValueExtractor} to extract value with
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the extracted value
*/
public CompletableFuture get(ID id, ValueExtractor super T, ? extends R> extractor)
{
return getMapInternal().invoke(id, Processors.extract(extractor));
}
/**
* Return all entities in this repository.
*
* @return a {@link CompletableFuture} that will resolve to all entities in this repository
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> getAll()
{
return (CompletableFuture) getMapInternal().values();
}
/**
* Stream all entities all entities in this repository.
*
* @param callback a {@link Consumer consumer} of results as they become available
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
* @see #getAll()
*/
public CompletableFuture getAll(Consumer super T> callback)
{
return getMapInternal().values(callback);
}
/**
* Return a map of values extracted from all entities in the repository.
*
* @param extractor the {@link ValueExtractor} to extract values with
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that will resolve to a map of extracted values, keyed by entity id
* @see #get(Object, ValueExtractor)
*/
public CompletableFuture> getAll(ValueExtractor super T, ? extends R> extractor)
{
return getAll(Filters.always(), extractor);
}
/**
* Streams the id and the associated extracted value from all entities in the repository.
*
* @param extractor the {@link ValueExtractor} to extract values with
* @param callback a {@link BiConsumer consumer} of results as they become available
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
* @see #getAll(ValueExtractor)
*/
public CompletableFuture getAll(ValueExtractor super T, ? extends R> extractor,
BiConsumer super ID, ? super R> callback)
{
return getAll(Filters.always(), extractor, callback);
}
/**
* Return the entities with the specified identifiers.
*
* @param colIds the entity identifiers
*
* @return a {@link CompletableFuture} that will resolve to the entities with the specified identifiers
*/
public CompletableFuture> getAll(Collection extends ID> colIds)
{
return getMapInternal().getAll(colIds).thenApply(Map::values);
}
/**
* Stream the entities associated with the specified ids to the provided callback.
*
* @param colIds a {@link Collection} of ids that may be present in this repository
* @param callback a {@link Consumer consumer} of results as they become available
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
* @see #getAll(Collection)
*/
public CompletableFuture getAll(Collection extends ID> colIds, Consumer super T> callback)
{
return getMapInternal().getAll(colIds, entry -> callback.accept(entry.getValue()));
}
/**
* Return a map of values extracted from a set of entities with the given
* identifiers.
*
* @param colIds the entity identifiers
* @param extractor the {@link ValueExtractor} to extract values with
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that will resolve to a map of extracted values, keyed by entity id
* @see #get(Object, ValueExtractor)
*/
public CompletableFuture> getAll(Collection extends ID> colIds,
ValueExtractor super T, ? extends R> extractor)
{
return getMapInternal().invokeAll(colIds, Processors.extract(extractor));
}
/**
* Stream the entities associated with the specified ids to the provided callback.
*
* @param colIds a {@link Collection} of ids that may be present in this repository
* @param extractor the {@link ValueExtractor} to extract values with
* @param callback a {@link BiConsumer consumer} of results as they become available
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
* @see #getAll(Collection)
*/
public CompletableFuture getAll(Collection extends ID> colIds,
ValueExtractor super T, ? extends R> extractor, BiConsumer super ID, ? super R> callback)
{
return getMapInternal().invokeAll(colIds, Processors.extract(extractor), callback);
}
/**
* Return all entities that satisfy the specified criteria.
*
* @param filter the criteria to evaluate
*
* @return a {@link CompletableFuture} that will resolve to all entities that satisfy the specified criteria
*/
public CompletableFuture> getAll(Filter> filter)
{
return getMapInternal().values(filter);
}
/**
* Stream all entities that satisfy the specified criteria.
*
* @param filter the criteria to evaluate
* @param callback a consumer of results as they become available
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
* @see #getAll(Filter)
*/
public CompletableFuture getAll(Filter> filter, Consumer super T> callback)
{
return getMapInternal().values(filter, callback);
}
/**
* Return a map of values extracted from a set of entities based on the
* specified criteria.
*
* @param filter the criteria to use to select entities for extraction
* @param extractor the {@link ValueExtractor} to extract values with
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that will resolve to a map of extracted values, keyed by entity id
* @see #get(Object, ValueExtractor)
*/
public CompletableFuture> getAll(Filter> filter, ValueExtractor super T, ? extends R> extractor)
{
return getMapInternal().invokeAll(filter, Processors.extract(extractor));
}
/**
* Streams the id and the associated extracted value from a set of entities based on the
* specified criteria.
*
* @param filter the criteria to use to select entities for extraction
* @param extractor the {@link ValueExtractor} to extract values with
* @param callback a {@link BiConsumer consumer} of results as they become available
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
* @see #getAll(Filter, ValueExtractor)
*/
public CompletableFuture getAll(Filter> filter, ValueExtractor super T, ? extends R> extractor,
BiConsumer super ID, ? super R> callback)
{
return getMapInternal().invokeAll(filter, Processors.extract(extractor), callback);
}
/**
* Return all entities in this repository, sorted using
* specified {@link Comparable} attribute.
*
* @param orderBy the {@link Comparable} attribute to sort the results by
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that will resolve to all entities in this repository, sorted using
* specified {@link Comparable} attribute.
*/
public > CompletableFuture> getAllOrderedBy(
ValueExtractor super T, ? extends R> orderBy)
{
return getAllOrderedBy(Filters.always(), Remote.comparator(orderBy));
}
/**
* Return all entities that satisfy the specified criteria, sorted using
* specified {@link Comparable} attribute.
*
* @param filter the criteria to evaluate
* @param orderBy the {@link Comparable} attribute to sort the results by
* @param the type of the extracted values
*
* @return a {@link CompletableFuture} that will resolve to all entities that satisfy specified criteria,
* sorted using specified {@link Comparable} attribute.
*/
public > CompletableFuture> getAllOrderedBy(
Filter> filter, ValueExtractor super T, ? extends R> orderBy)
{
return getAllOrderedBy(filter, Remote.comparator(orderBy));
}
/**
* Return all entities in this repository, sorted using
* specified {@link Remote.Comparator}.
*
* @param orderBy the comparator to sort the results with
*
* @return a {@link CompletableFuture} that will resolve to all entities in this repository, sorted using
* specified {@link Remote.Comparator}.
*/
public CompletableFuture> getAllOrderedBy(Remote.Comparator super T> orderBy)
{
return getAllOrderedBy(Filters.always(), orderBy);
}
/**
* Return all entities that satisfy the specified criteria, sorted using
* specified {@link Remote.Comparator}.
*
* @param filter the criteria to evaluate
* @param orderBy the comparator to sort the results with
*
* @return a {@link CompletableFuture} that will resolve to all entities that satisfy specified criteria,
* sorted using specified {@link Remote.Comparator}.
*/
public CompletableFuture> getAllOrderedBy(Filter> filter, Remote.Comparator super T> orderBy)
{
return getMapInternal().values(filter, orderBy);
}
/**
* Update an entity using specified updater and the new value.
*
* For example, you could update {@code Person}'s {@code age} attribute by
* calling a setter on a remote {@code Person} entity instance:
*
* people.update(ssn, Person::setAge, 21);
*
* Note that the actual update (via the invocation of the specified setter
* method) will happen on the primary owner for the specified entity, and
* the updater will have exclusive access to an entity during the
* execution.
*
* @param id the entity's identifier
* @param updater the updater function to use
* @param value the value to update entity with, which will be passed as
* an argument to the updater function
* @param the type of value to update
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
*/
public CompletableFuture update(ID id, ValueUpdater super T, ? super U> updater, U value)
{
return update(id, updater, value, null);
}
/**
* Update an entity using specified updater and the new value, and optional
* {@link EntityFactory} that will be used to create entity instance if it
* doesn't already exist in the repository.
*
* For example, you could update {@code Person}'s {@code age} attribute by
* calling a setter on a remote {@code Person} entity instance:
*
* people.update(ssn, Person::setAge, 21, Person::new);
*
* If the person with the specified identifier does not exist, the {@link
* EntityFactory} will be used to create a new instance. In the example
* above, it will invoke a constructor on the {@code Person} class that
* takes identifier as an argument.
*
* Note that the actual update (via the invocation of the specified setter
* method) will happen on the primary owner for the specified entity, and
* the updater will have exclusive access to an entity during the
* execution.
*
* @param id the entity's identifier
* @param updater the updater function to use
* @param value the value to update entity with, which will be passed as
* an argument to the updater function
* @param the type of value to update
* @param factory the entity factory to use to create new entity instance
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
*/
public CompletableFuture update(ID id, ValueUpdater super T, ? super U> updater, U value,
EntityFactory super ID, ? extends T> factory)
{
return getMapInternal().invoke(id, updaterProcessor(updater, value, factory));
}
/**
* Update an entity using specified updater function.
*
* For example, you could increment {@code Person}'s {@code age} attribute
* and return the updated {@code Person} entity:
*
* people.update(ssn, person ->
* {
* person.setAge(person.getAge() + 1);
* return person;
* });
*
* This variant of the {@code update} method offers ultimate flexibility, as
* it allows you to return any value you want as the result of the
* invocation, at the cost of typically slightly more complex logic at the
* call site.
*
* Note that the actual update (via the evaluation of the specified
* function) will happen on the primary owner for the specified entity, and
* the updater will have exclusive access to an entity during the
* execution.
*
* @param id the entity's identifier
* @param updater the updater function to use
* @param the type of return value of the updater function
*
* @return a {@link CompletableFuture} that will resolve to the result of updater function evaluation
*/
public CompletableFuture update(ID id, Remote.Function super T, ? extends R> updater)
{
return update(id, updater, null);
}
/**
* Update an entity using specified updater function, and optional {@link
* EntityFactory} that will be used to create entity instance if it doesn't
* already exist in the repository.
*
* For example, you could increment {@code Person}'s {@code age} attribute
* and return the updated {@code Person} entity:
*
* people.update(ssn, person ->
* {
* person.setAge(person.getAge() + 1);
* return person;
* }, Person::new);
*
* If the person with the specified identifier does not exist, the {@link
* EntityFactory} will be used to create a new instance. In the example
* above, it will invoke a constructor on the {@code Person} class that
* takes identifier as an argument.
*
* This variant of the {@code update} method offers ultimate flexibility, as
* it allows you to return any value you want as the result of the
* invocation, at the cost of typically slightly more complex logic at the
* call site.
*
* Note that the actual update (via the evaluation of the specified
* function) will happen on the primary owner for the specified entity, and
* the updater will have exclusive access to an entity during the
* execution.
*
* @param id the entity's identifier
* @param updater the updater function to use
* @param factory the entity factory to use to create new entity instance
* @param the type of return value of the updater function
*
* @return a {@link CompletableFuture} that will resolve to the result of updater function evaluation
*/
public CompletableFuture update(ID id, Remote.Function super T, ? extends R> updater,
EntityFactory super ID, ? extends T> factory)
{
return getMapInternal().invoke(id, updateFunctionProcessor(updater, factory));
}
/**
* Update an entity using specified updater and the new value.
*
* Unlike {@link #update(Object, ValueUpdater, Object)}, which doesn't
* return anything, this method is typically used to invoke "fluent" methods
* on the target entity that return entity itself (although they are free to
* return any value they want).
*
* For example, you could use it to add an item to the {@code ShoppingCart}
* entity and return the updated {@code ShoppingCart} instance in a single
* call:
*
* Item item = ...
* ShoppingCart cart = carts.update(cartId, ShoppingCart::addItem, item);
*
* Note that the actual update (via the invocation of the specified setter
* method) will happen on the primary owner for the specified entity, and
* the updater will have exclusive access to an entity during the
* execution.
*
* @param id the entity's identifier
* @param updater the updater function to use
* @param value the value to update entity with, which will be passed as
* an argument to the updater function
* @param the type of value to update
* @param the type of return value of the updater function
*
* @return a {@link CompletableFuture} that will resolve to the result of updater function evaluation
*/
public CompletableFuture update(ID id, Remote.BiFunction super T, ? super U, ? extends R> updater,
U value)
{
return update(id, updater, value, null);
}
/**
* Update an entity using specified updater function, and optional {@link
* EntityFactory} that will be used to create entity instance if it doesn't
* already exist in the repository.
*
* Unlike {@link #update(Object, ValueUpdater, Object)}, which doesn't
* return anything, this method is typically used to invoke "fluent" methods
* on the target entity that return entity itself (although they are free to
* return any value they want).
*
* For example, you could use it to add an item to the {@code ShoppingCart}
* entity and return the updated {@code ShoppingCart} instance in a single
* call:
*
* Item item = ...
* ShoppingCart cart = carts.update(cartId, ShoppingCart::addItem, item, ShoppingCart::new);
*
* If the cart with the specified identifier does not exist, the specified
* {@link EntityFactory} will be used to create a new instance. In the
* example above, it will invoke a constructor on the {@code ShoppingCart}
* class that takes identifier as an argument.
*
* Note that the actual update (via the evaluation of the specified
* function) will happen on the primary owner for the specified entity, and
* the updater will have exclusive access to an entity during the
* execution.
*
* @param id the entity's identifier
* @param updater the updater function to use
* @param value the value to update entity with, which will be passed as
* an argument to the updater function
* @param factory the entity factory to use to create new entity instance
* @param the type of value to update
* @param the type of return value of the updater function
*
* @return a {@link CompletableFuture} that will resolve to the result of updater function evaluation
*/
public CompletableFuture update(ID id, Remote.BiFunction super T, ? super U, ? extends R> updater,
U value, EntityFactory super ID, ? extends T> factory)
{
return getMapInternal().invoke(id, updateBiFunctionProcessor(updater, value, factory));
}
/**
* Update multiple entities using specified updater and the new value.
*
* @param filter the criteria to use to select entities to update
* @param updater the updater function to use
* @param value the value to update each entity with, which will be passed
* as an argument to the updater function
* @param the type of value to update
*
* @return a {@link CompletableFuture} that can be used to determine whether
* the operation completed
*/
@SuppressWarnings("CheckStyle")
public CompletableFuture updateAll(Filter> filter, ValueUpdater super T, ? super U> updater,
U value)
{
return getMapInternal().invokeAll(filter, updaterProcessor(updater, value, null)).thenAccept(m -> {});
}
/**
* Update multiple entities using specified updater function.
*
* @param filter the criteria to use to select entities to update
* @param updater the updater function to use
* @param the type of return value of the updater function
*
* @return a {@link CompletableFuture} that will resolve to a map of updater function results, keyed by entity id
*/
public CompletableFuture> updateAll(Filter> filter,
Remote.Function super T, ? extends R> updater)
{
return getMapInternal().invokeAll(filter, updateFunctionProcessor(updater, null));
}
/**
* Update multiple entities using specified updater and the new value.
*
* @param filter the criteria to use to select entities to update
* @param updater the updater function to use
* @param value the value to update each entity with, which will be passed
* as an argument to the updater function
* @param the type of value to update
* @param the type of return value of the updater function
*
* @return a {@link CompletableFuture} that will resolve to a map of updater function results, keyed by entity id
*/
public CompletableFuture> updateAll(Filter> filter,
Remote.BiFunction super T, ? super U, ? extends R> updater, U value)
{
return getMapInternal().invokeAll(filter, updateBiFunctionProcessor(updater, value, null));
}
/**
* Remove the entity with a specified identifier.
*
* @param id the identifier of an entity to remove, if present
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository contained
* the specified entity
*/
public CompletableFuture removeById(ID id)
{
return getMapInternal().invoke(id, Processors.remove());
}
/**
* Remove the entity with a specified identifier.
*
* @param id the identifier of an entity to remove
* @param fReturn the flag specifying whether to return removed entity
*
* @return a {@link CompletableFuture} that will resolve to the removed entity, iff {@code fReturn == true};
* {@code null} otherwise
*/
public CompletableFuture removeById(ID id, boolean fReturn)
{
return getMapInternal().invoke(id, Processors.remove(fReturn));
}
/**
* Remove the specified entity.
*
* @param entity the entity to remove
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository contained
* the specified entity
*/
public CompletableFuture remove(T entity)
{
return removeById(getId(entity));
}
/**
* Remove the specified entity.
*
* @param entity the entity to remove
* @param fReturn the flag specifying whether to return removed entity
*
* @return a {@link CompletableFuture} that will resolve to the removed entity, iff {@code fReturn == true};
* {@code null} otherwise
*/
public CompletableFuture remove(T entity, boolean fReturn)
{
return removeById(getId(entity), fReturn);
}
/**
* Remove entities with the specified identifiers.
*
* @param colIds the identifiers of the entities to remove
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository changed
* as a result of the call
*/
public CompletableFuture removeAllById(Collection extends ID> colIds)
{
return getMapInternal().invokeAll(colIds, Processors.remove())
.thenApply(idBooleanMap ->
{
for (boolean fResult : idBooleanMap.values())
{
if (fResult)
{
return true;
}
}
return false;
});
}
/**
* Remove entities with the specified identifiers.
*
* @param colIds the identifiers of the entities to remove
* @param fReturn the flag specifying whether to return removed entity
*
* @return a {@link CompletableFuture} that will resolve to a map of removed entity identifiers as keys,
* and the removed entities as values iff {@code fReturn == true}; {@code null} otherwise
*/
public CompletableFuture> removeAllById(Collection extends ID> colIds, boolean fReturn)
{
return getMapInternal().invokeAll(colIds, Processors.remove(fReturn));
}
/**
* Remove the specified entities.
*
* @param colEntities the entities to remove
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository changed
* as a result of the call
*/
public CompletableFuture removeAll(Collection extends T> colEntities)
{
return removeAll(colEntities.stream());
}
/**
* Remove the specified entities.
*
* @param colEntities the entities to remove
* @param fReturn the flag specifying whether to return removed entity
*
* @return a {@link CompletableFuture} that will resolve to a map of removed entity identifiers as keys,
* and the removed entities as values iff {@code fReturn == true}; {@code null} otherwise
*/
public CompletableFuture> removeAll(Collection extends T> colEntities, boolean fReturn)
{
return removeAll(colEntities.stream(), fReturn);
}
/**
* Remove the specified entities.
*
* @param strEntities the entities to remove
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository changed
* as a result of the call
*/
public CompletableFuture removeAll(Stream extends T> strEntities)
{
return removeAllById(strEntities.map(this::getId).collect(Collectors.toSet()));
}
/**
* Remove the specified entities.
*
* @param strEntities the entities to remove
* @param fReturn the flag specifying whether to return removed entity
*
* @return a {@link CompletableFuture} that will resolve to a map of removed entity identifiers as keys,
* and the removed entities as values iff {@code fReturn == true}; {@code null} otherwise
*/
public CompletableFuture> removeAll(Stream extends T> strEntities, boolean fReturn)
{
return removeAllById(strEntities.map(this::getId).collect(Collectors.toSet()), fReturn);
}
/**
* Remove all entities based on the specified criteria.
*
* @param filter the criteria that should be used to select entities to
* remove
*
* @return a {@link CompletableFuture} that will resolve to {@code true} if this repository changed
* as a result of the call
*/
public CompletableFuture removeAll(Filter> filter)
{
return getMapInternal().invokeAll(filter, Processors.remove())
.thenApply(idBooleanMap ->
{
for (boolean fResult : idBooleanMap.values())
{
if (fResult)
{
return true;
}
}
return false;
});
}
/**
* Remove all entities based on the specified criteria.
*
* @param filter the criteria that should be used to select entities to
* remove
* @param fReturn the flag specifying whether to return removed entity
*
* @return a {@link CompletableFuture} that will resolve to a map of removed entity identifiers as keys,
* and the removed entities as values iff {@code fReturn == true}; {@code null} otherwise
*/
public CompletableFuture> removeAll(Filter> filter, boolean fReturn)
{
return getMapInternal().invokeAll(filter, Processors.remove(fReturn));
}
// ---- aggregation support ---------------------------------------------
/**
* Return the number of entities in this repository.
*
* @return a {@link CompletableFuture} that will resolve to the number of entities in this repository
*/
public CompletableFuture count()
{
return getMapInternal().aggregate(Aggregators.count()).thenApply(Integer::longValue);
}
/**
* Return the number of entities in this repository that satisfy specified
* filter.
*
* @param filter the filter to evaluate
*
* @return a {@link CompletableFuture} that will resolve to the number of entities in this repository
* that satisfy specified filter
*/
public CompletableFuture count(Filter> filter)
{
return getMapInternal().aggregate(filter, Aggregators.count()).thenApply(Integer::longValue);
}
/**
* Return the maximum value of the specified function.
*
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.max(extractor)).thenApply(Long::intValue);
}
/**
* Return the maximum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Filter> filter, Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.max(extractor)).thenApply(Long::intValue);
}
/**
* Return the maximum value of the specified function.
*
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Filter> filter, Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Filter> filter, Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public CompletableFuture max(Filter> filter, Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getName}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public > CompletableFuture max(
Remote.ToComparableFunction super T, R> extractor)
{
return getMapInternal().aggregate(Aggregators.max(extractor));
}
/**
* Return the maximum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getName}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the maximum value of the specified function
*/
public > CompletableFuture max(
Filter> filter,
Remote.ToComparableFunction super T, R> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.max(extractor));
}
/**
* Return the entity with the maximum value of the specified function.
*
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the entity with the maximum value
* of the specified function
*/
public > CompletableFuture> maxBy(
ValueExtractor super T, ? extends R> extractor)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream()
.map(Map.Entry::getValue)
.reduce(Remote.BinaryOperator.maxBy(comparing(extractor))));
}
/**
* Return the entity with the maximum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the maximum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the entity with the maximum value
* of the specified function
*/
public > CompletableFuture> maxBy(
Filter> filter, ValueExtractor super T, ? extends R> extractor)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream(filter)
.map(Map.Entry::getValue)
.reduce(Remote.BinaryOperator.maxBy(comparing(extractor))));
}
/**
* Return the minimum value of the specified function.
*
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.min(extractor)).thenApply(Long::intValue);
}
/**
* Return the minimum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Filter> filter, Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.min(extractor)).thenApply(Long::intValue);
}
/**
* Return the minimum value of the specified function.
*
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Filter> filter, Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Filter> filter, Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public CompletableFuture min(Filter> filter, Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getName}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public > CompletableFuture min(
Remote.ToComparableFunction super T, R> extractor)
{
return getMapInternal().aggregate(Aggregators.min(extractor));
}
/**
* Return the minimum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getName}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the minimum value of the specified function
*/
public > CompletableFuture min(Filter> filter,
Remote.ToComparableFunction super T, R> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.min(extractor));
}
/**
* Return the entity with the minimum value of the specified function.
*
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the entity with the minimum value
* of the specified function
*/
public > CompletableFuture> minBy(
ValueExtractor super T, ? extends R> extractor)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream()
.map(Map.Entry::getValue)
.reduce(Remote.BinaryOperator.minBy(comparing(extractor))));
}
/**
* Return the entity with the minimum value of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to determine the minimum value for;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
* @param the type of the extracted value
*
* @return a {@link CompletableFuture} that will resolve to the entity with the minimum value
* of the specified function
*/
public > CompletableFuture> minBy(Filter> filter,
ValueExtractor super T, ? extends R> extractor)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream(filter)
.map(Map.Entry::getValue)
.reduce(Remote.BinaryOperator.minBy(comparing(extractor))));
}
/**
* Return the sum of the specified function.
*
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Filter> filter, Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Filter> filter, Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Filter> filter, Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.sum(extractor));
}
/**
* Return the sum of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to sum;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the sum of the specified function
*/
public CompletableFuture sum(Filter> filter, Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.sum(extractor));
}
/**
* Return the average of the specified function.
*
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Filter> filter, Remote.ToIntFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getAge}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Filter> filter, Remote.ToLongFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getWeight}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Filter> filter, Remote.ToDoubleFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(Aggregators.average(extractor));
}
/**
* Return the average of the specified function.
*
* @param filter the entity selection criteria
* @param extractor the function to average;
* typically a method reference on the entity class,
* such as {@code Person::getSalary}
*
* @return a {@link CompletableFuture} that will resolve to the average of the specified function
*/
public CompletableFuture average(Filter> filter, Remote.ToBigDecimalFunction super T> extractor)
{
return getMapInternal().aggregate(filter, Aggregators.average(extractor));
}
/**
* Return the set of distinct values for the specified extractor.
*
* @param extractor the extractor to get a value from;
* typically a method reference on the entity class,
* such as {@code Person::getName}
* @param the type of extracted values
*
* @return a {@link CompletableFuture} that will resolve to a set of distinct values for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> distinct(ValueExtractor super T, ? extends R> extractor)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.distinctValues(extractor);
return getMapInternal().aggregate(aggregator);
}
/**
* Return the set of distinct values for the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get a value from;
* typically a method reference on the entity class,
* such as {@code Person::getName}
* @param the type of extracted values
*
* @return a {@link CompletableFuture} that will resolve to a set of distinct values for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> distinct(Filter> filter,
ValueExtractor super T, ? extends R> extractor)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.distinctValues(extractor);
return getMapInternal().aggregate(filter, aggregator);
}
/**
* Return the grouping of entities by the specified extractor.
*
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param the type of extracted grouping keys
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be sets of entities that match each extracted key
*/
public CompletableFuture>> groupBy(ValueExtractor super T, ? extends K> extractor)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream()
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, RemoteCollectors.toSet())));
}
/**
* Return the grouping of entities by the specified extractor, ordered by
* the specified attribute within each group.
*
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param orderBy the {@link Remote.Comparator} to sort the results
* within each group by
* @param the type of extracted grouping keys
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be sets of entities that match each extracted key
*/
public CompletableFuture>> groupBy(ValueExtractor super T, ? extends K> extractor,
Remote.Comparator super T> orderBy)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream()
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, RemoteCollectors.toSortedSet(orderBy))));
}
/**
* Return the grouping of entities by the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param the type of extracted grouping keys
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be sets of entities that match each extracted key
*/
public CompletableFuture>> groupBy(Filter> filter,
ValueExtractor super T, ? extends K> extractor)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream(filter)
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, RemoteCollectors.toSet())));
}
/**
* Return the grouping of entities by the specified extractor, ordered by
* the specified attribute within each group.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param orderBy the {@link Remote.Comparator} to sort the results
* within each group by
* @param the type of extracted grouping keys
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be sets of entities that match each extracted key
*/
public CompletableFuture>> groupBy(Filter> filter,
ValueExtractor super T, ? extends K> extractor, Remote.Comparator super T> orderBy)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream(filter)
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, RemoteCollectors.toSortedSet(orderBy))));
}
/**
* Return the grouping of entities by the specified extractor.
*
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param collector the {@link RemoteCollector} to apply to grouped entities
* @param the type of extracted grouping keys
* @param the type of collector's accumulator
* @param the type of collector's result
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be results of the specified {@code collector} for each group
*
* @see RemoteCollectors
*/
public CompletableFuture> groupBy(ValueExtractor super T, ? extends K> extractor,
RemoteCollector super T, A, R> collector)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream()
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, collector)));
}
/**
* Return the grouping of entities by the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param collector the {@link RemoteCollector} to apply to grouped entities
* @param the type of extracted grouping keys
* @param the type of collector's accumulator
* @param the type of collector's result
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be results of the specified {@code collector} for each group
*
* @see RemoteCollectors
*/
public CompletableFuture> groupBy(Filter> filter,
ValueExtractor super T, ? extends K> extractor, RemoteCollector super T, A, R> collector)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream(filter)
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, collector)));
}
/**
* Return the grouping of entities by the specified extractor.
*
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param mapFactory the supplier to use to create result {@code Map}
* @param collector the {@link RemoteCollector} to apply to grouped entities
* @param the type of extracted grouping keys
* @param the type of collector's accumulator
* @param the type of collector's result
* @param the type of result {@code Map}
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be results of the specified {@code collector} for each group
*
* @see RemoteCollectors
*/
public > CompletableFuture groupBy(ValueExtractor super T, ? extends K> extractor,
Remote.Supplier mapFactory, RemoteCollector super T, A, R> collector)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream()
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, mapFactory, collector)));
}
/**
* Return the grouping of entities by the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get a grouping value from;
* typically a method reference on the entity class,
* such as {@code Person::getGender}
* @param mapFactory the supplier to use to create result {@code Map}
* @param collector the {@link RemoteCollector} to apply to grouped entities
* @param the type of extracted grouping keys
* @param the type of collector's accumulator
* @param the type of collector's result
* @param the type of result {@code Map}
*
* @return a {@link CompletableFuture} that will resolve to a grouping of entities by the specified extractor;
* the keys in the returned map will be distinct values extracted by the specified {@code extractor},
* and the values will be results of the specified {@code collector} for each group
*
* @see RemoteCollectors
*/
public > CompletableFuture groupBy(Filter> filter,
ValueExtractor super T, ? extends K> extractor, Remote.Supplier mapFactory,
RemoteCollector super T, A, R> collector)
{
return CompletableFuture.supplyAsync(() -> getNamedMap().stream(filter)
.map(Map.Entry::getValue)
.collect(groupingBy(extractor, mapFactory, collector)));
}
/**
* Return the top N highest values for the specified extractor.
*
* @param extractor the extractor to get the values to compare with
* @param cResults the number of highest values to return
* @param the type of returned values
*
* @return a {@link CompletableFuture} that will resolve to the top N highest values for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public > CompletableFuture> top(
ValueExtractor super T, ? extends R> extractor,
int cResults)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.topN(extractor, cResults);
return getMapInternal()
.aggregate(aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N highest values for the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get the values to compare with
* @param cResults the number of highest values to return
* @param the type of returned values
*
* @return a {@link CompletableFuture} that will resolve to the top N highest values for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public > CompletableFuture> top(Filter> filter,
ValueExtractor super T, ? extends R> extractor, int cResults)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.topN(extractor, cResults);
return getMapInternal()
.aggregate(filter, aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N highest values for the specified extractor.
*
* @param extractor the extractor to get the values to compare with
* @param comparator the comparator to use when comparing extracted values
* @param cResults the number of highest values to return
* @param the type of returned values
*
* @return a {@link CompletableFuture} that will resolve to the top N highest values for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> top(ValueExtractor super T, ? extends R> extractor,
Remote.Comparator super R> comparator, int cResults)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.topN(extractor, comparator, cResults);
return getMapInternal()
.aggregate(aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N highest values for the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get the values to compare with
* @param comparator the comparator to use when comparing extracted values
* @param cResults the number of highest values to return
* @param the type of returned values
*
* @return a {@link CompletableFuture} that will resolve to the top N highest values for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> top(Filter> filter, ValueExtractor super T, ? extends R> extractor,
Remote.Comparator super R> comparator, int cResults)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.topN(extractor, comparator, cResults);
return getMapInternal()
.aggregate(filter, aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N entities with the highest values for the specified extractor.
*
* @param extractor the extractor to get the values to compare with
* @param cResults the number of highest values to return
* @param the type of values used for comparison
*
* @return a {@link CompletableFuture} that will resolve to the top N entities with the highest values
* for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public > CompletableFuture> topBy(
ValueExtractor super T, ? extends R> extractor, int cResults)
{
InvocableMap.StreamingAggregator aggregator =
Aggregators.topN(ValueExtractor.identity(), new ExtractorComparator<>(extractor), cResults);
return getMapInternal()
.aggregate(aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N entities with the highest values for the specified extractor.
*
* @param filter the entity selection criteria
* @param extractor the extractor to get the values to compare with
* @param cResults the number of highest values to return
* @param the type of values used for comparison
*
* @return a {@link CompletableFuture} that will resolve to the top N entities with the highest values
* for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public > CompletableFuture> topBy(Filter> filter,
ValueExtractor super T, ? extends R> extractor, int cResults)
{
InvocableMap.StreamingAggregator aggregator =
Aggregators.topN(ValueExtractor.identity(), new ExtractorComparator<>(extractor), cResults);
return getMapInternal()
.aggregate(filter, aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N entities with the highest values for the specified extractor.
*
* @param comparator the comparator to use when comparing extracted values
* @param cResults the number of highest values to return
*
* @return a {@link CompletableFuture} that will resolve to the top N entities with the highest value
* for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> topBy(Remote.Comparator super T> comparator, int cResults)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.topN(ValueExtractor.identity(), comparator, cResults);
return getMapInternal()
.aggregate(aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
/**
* Return the top N entities with the highest values for the specified extractor.
*
* @param filter the entity selection criteria
* @param comparator the comparator to use when comparing extracted values
* @param cResults the number of highest values to return
*
* @return a {@link CompletableFuture} that will resolve to the top N entities with the highest values
* for the specified extractor
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public CompletableFuture> topBy(Filter> filter, Remote.Comparator super T> comparator, int cResults)
{
InvocableMap.StreamingAggregator aggregator = Aggregators.topN(ValueExtractor.identity(), comparator, cResults);
return getMapInternal()
.aggregate(filter, aggregator)
.thenApply(rs -> Arrays.stream((Object[]) rs).collect(Collectors.toList()));
}
// ---- helpers ---------------------------------------------------------
/**
* Ensures that this repository is initialized when accessed for the first
* time, and calls {@link #getMap()}.
*
* @return the {@link AsyncNamedMap} returned by the {@link #getMap()} method
*/
private AsyncNamedMap getMapInternal()
{
ensureInitialized();
return getMap();
}
}