Skip to content

Commit 8058492

Browse files
Introduce Predicate-based QueryEngine.
Closes: #565
1 parent 793db8a commit 8058492

File tree

7 files changed

+1128
-466
lines changed

7 files changed

+1128
-466
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.keyvalue.core;
17+
18+
import java.util.Collection;
19+
import java.util.Comparator;
20+
import java.util.List;
21+
import java.util.function.Predicate;
22+
import java.util.stream.Collectors;
23+
import java.util.stream.Stream;
24+
25+
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
26+
import org.springframework.lang.Nullable;
27+
28+
/**
29+
* {@link QueryEngine} implementation specific for executing {@link Predicate} based {@link KeyValueQuery} against
30+
* {@link KeyValueAdapter}.
31+
*
32+
* @author Christoph Strobl
33+
* @since 3.3
34+
*/
35+
class PredicateQueryEngine extends QueryEngine<KeyValueAdapter, Predicate<?>, Comparator<?>> {
36+
37+
/**
38+
* Creates a new {@link PredicateQueryEngine}.
39+
*/
40+
public PredicateQueryEngine() {
41+
this(new PathSortAccessor());
42+
}
43+
44+
/**
45+
* Creates a new query engine using provided {@link SortAccessor accessor} for sorting results.
46+
*/
47+
public PredicateQueryEngine(SortAccessor<Comparator<?>> sortAccessor) {
48+
super(new CriteriaAccessor<>() {
49+
@Nullable
50+
@Override
51+
public Predicate<?> resolve(KeyValueQuery<?> query) {
52+
return (Predicate<?>) query.getCriteria();
53+
}
54+
}, sortAccessor);
55+
}
56+
57+
@Override
58+
public Collection<?> execute(@Nullable Predicate<?> criteria, @Nullable Comparator<?> sort, long offset, int rows,
59+
String keyspace) {
60+
return sortAndFilterMatchingRange(getRequiredAdapter().getAllOf(keyspace), criteria, sort, offset, rows);
61+
}
62+
63+
@Override
64+
public long count(@Nullable Predicate<?> criteria, String keyspace) {
65+
return filterMatchingRange(IterableConverter.toList(getRequiredAdapter().getAllOf(keyspace)), criteria, -1, -1)
66+
.size();
67+
}
68+
69+
@SuppressWarnings({ "unchecked", "rawtypes" })
70+
private List<?> sortAndFilterMatchingRange(Iterable<?> source, @Nullable Predicate<?> criteria,
71+
@Nullable Comparator sort, long offset, int rows) {
72+
73+
List<?> tmp = IterableConverter.toList(source);
74+
if (sort != null) {
75+
tmp.sort(sort);
76+
}
77+
78+
return filterMatchingRange(tmp, criteria, offset, rows);
79+
}
80+
81+
private static <S> List<S> filterMatchingRange(List<S> source, @Nullable Predicate criteria, long offset, int rows) {
82+
83+
Stream<S> stream = source.stream();
84+
85+
if (criteria != null) {
86+
stream = stream.filter(criteria);
87+
}
88+
if (offset > 0) {
89+
stream = stream.skip(offset);
90+
}
91+
if (rows > 0) {
92+
stream = stream.limit(rows);
93+
}
94+
95+
return stream.collect(Collectors.toList());
96+
}
97+
}

src/main/java/org/springframework/data/keyvalue/core/SimplePropertyPathAccessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
* @author Christoph Strobl
2424
* @since 3.1.10
2525
*/
26-
class SimplePropertyPathAccessor<T> {
26+
public class SimplePropertyPathAccessor<T> {
2727

2828
private final Object root;
2929

3030
public SimplePropertyPathAccessor(Object source) {
3131
this.root = source;
3232
}
3333

34-
Object getValue(PropertyPath path) {
34+
public Object getValue(PropertyPath path) {
3535

3636
Object currentValue = root;
3737
for (PropertyPath current : path) {

0 commit comments

Comments
 (0)