PredicateFilterMessageStoreSearcher.java
package net.morimekta.providence.storage;
import net.morimekta.providence.PMessage;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Simple store searcher that finds all messages in a given store that matches
* a simple java predicate. Note that this will always load all the data from
* the store in order to do the search.
*
* @param <Q> The query type.
* @param <K> The store's key type.
* @param <M> The message type in the store.
*/
public class PredicateFilterMessageStoreSearcher<Q, K, M extends PMessage<M>>
implements MessageSearcher<Q, M> {
public interface PredicateFilter<Q, K, M extends PMessage<M>> {
boolean test(K key, M message, Q query);
}
private final MessageReadOnlyStore<K, M> store;
private final PredicateFilter<Q, K, M> predicate;
public PredicateFilterMessageStoreSearcher(MessageReadOnlyStore<K, M> store,
BiPredicate<M, Q> biPredicate) {
this(store, (key, message, query) -> biPredicate.test(message, query));
}
public PredicateFilterMessageStoreSearcher(MessageReadOnlyStore<K, M> store,
PredicateFilter<Q, K, M> predicate) {
this.store = store;
this.predicate = predicate;
}
@Nonnull
@Override
public List<M> search(@Nonnull Q query) {
return stream(query).collect(Collectors.toList());
}
@Nonnull
@Override
public Stream<M> stream(@Nonnull Q query) {
return store.getAll(store.keys())
.entrySet()
.stream()
.filter(entry -> predicate.test(entry.getKey(), entry.getValue(), query))
.map(Map.Entry::getValue);
}
}