Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: optimize the implementation of indexed query engine through query index view #5233

Merged
merged 1 commit into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions api/src/main/java/run/halo/app/extension/index/KeyComparator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package run.halo.app.extension.index;

import java.util.Comparator;
import org.springframework.lang.Nullable;

public class KeyComparator implements Comparator<String> {
public static final KeyComparator INSTANCE = new KeyComparator();

@Override
public int compare(@Nullable String a, @Nullable String b) {
if (a == null && b == null) {
return 0;
} else if (a == null) {
// null less than everything
return 1;
} else if (b == null) {
// null less than everything
return -1;
}

int i = 0;
int j = 0;
while (i < a.length() && j < b.length()) {
if (Character.isDigit(a.charAt(i)) && Character.isDigit(b.charAt(j))) {
// handle number part
int num1 = 0;
int num2 = 0;
while (i < a.length() && Character.isDigit(a.charAt(i))) {
num1 = num1 * 10 + (a.charAt(i++) - '0');
}
while (j < b.length() && Character.isDigit(b.charAt(j))) {
num2 = num2 * 10 + (b.charAt(j++) - '0');
}
if (num1 != num2) {
return num1 - num2;
}
} else if (a.charAt(i) != b.charAt(j)) {
// handle non-number part
return a.charAt(i) - b.charAt(j);
} else {
i++;
j++;
}
}
return a.length() - b.length();
}
}
2 changes: 2 additions & 0 deletions api/src/main/java/run/halo/app/extension/index/query/And.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public NavigableSet<String> matches(QueryIndexView indexView) {
NavigableSet<String> resultSet = null;
for (Query query : childQueries) {
NavigableSet<String> currentResult = query.matches(indexView);
// Trim unneeded rows to shrink the dataset for the next query
indexView.removeByIdNotIn(currentResult);
if (resultSet == null) {
resultSet = Sets.newTreeSet(currentResult);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package run.halo.app.extension.index.query;

import java.util.NavigableSet;
import org.springframework.util.Assert;

public class EqualQuery extends SimpleQuery {

Expand All @@ -10,6 +11,7 @@ public EqualQuery(String fieldName, String value) {

public EqualQuery(String fieldName, String value, boolean isFieldRef) {
super(fieldName, value, isFieldRef);
Assert.notNull(value, "Value must not be null, use IsNull or IsNotNull instead");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package run.halo.app.extension.index.query;

import java.util.NavigableSet;

public class IsNotNull extends SimpleQuery {

protected IsNotNull(String fieldName) {
super(fieldName, null);
}

@Override
public NavigableSet<String> matches(QueryIndexView indexView) {
return indexView.getAllIdsForField(fieldName);
}
}
18 changes: 18 additions & 0 deletions api/src/main/java/run/halo/app/extension/index/query/IsNull.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package run.halo.app.extension.index.query;

import java.util.NavigableSet;

public class IsNull extends SimpleQuery {

protected IsNull(String fieldName) {
super(fieldName, null);
}

@Override
public NavigableSet<String> matches(QueryIndexView indexView) {
var allIds = indexView.getAllIds();
var idsForField = indexView.getAllIdsForField(fieldName);
allIds.removeAll(idsForField);
return allIds;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.collect.Sets;
import java.util.NavigableSet;
import org.springframework.util.Assert;

public class NotEqual extends SimpleQuery {
private final EqualQuery equalQuery;
Expand All @@ -12,6 +13,7 @@ public NotEqual(String fieldName, String value) {

public NotEqual(String fieldName, String value, boolean isFieldRef) {
super(fieldName, value, isFieldRef);
Assert.notNull(value, "Value must not be null, use IsNull or IsNotNull instead");
this.equalQuery = new EqualQuery(fieldName, value, isFieldRef);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,35 @@ public static Query all(String fieldName) {
return new All(fieldName);
}

public static Query isNull(String fieldName) {
return new IsNull(fieldName);
}

public static Query isNotNull(String fieldName) {
return new IsNotNull(fieldName);
}

/**
* Create a {@link NotEqual} for the given {@code fieldName} and {@code attributeValue}.
*/
public static Query notEqual(String fieldName, String attributeValue) {
if (attributeValue == null) {
return new IsNotNull(fieldName);
}
return new NotEqual(fieldName, attributeValue);
}

public static Query notEqualOtherField(String fieldName, String otherFieldName) {
return new NotEqual(fieldName, otherFieldName, true);
}

/**
* Create a {@link EqualQuery} for the given {@code fieldName} and {@code attributeValue}.
*/
public static Query equal(String fieldName, String attributeValue) {
if (attributeValue == null) {
return new IsNull(fieldName);
}
return new EqualQuery(fieldName, attributeValue);
}

Expand Down Expand Up @@ -73,6 +93,9 @@ public static Query in(String fieldName, String... attributeValues) {
return in(fieldName, Set.of(attributeValues));
}

/**
* Create an {@link InQuery} for the given {@code fieldName} and {@code values}.
*/
public static Query in(String fieldName, Collection<String> values) {
Assert.notNull(values, "Values must not be null");
if (values.size() == 1) {
Expand All @@ -85,6 +108,9 @@ public static Query in(String fieldName, Collection<String> values) {
return new InQuery(fieldName, valueSet);
}

/**
* Create an {@link And} for the given {@link Query}s.
*/
public static Query and(Collection<Query> queries) {
Assert.notEmpty(queries, "Queries must not be empty");
if (queries.size() == 1) {
Expand All @@ -98,6 +124,9 @@ public static And and(Query query1, Query query2) {
return new And(queries);
}

/**
* Create an {@link And} for the given {@link Query}s.
*/
public static Query and(Query query1, Query query2, Query... additionalQueries) {
var queries = new ArrayList<Query>(2 + additionalQueries.length);
queries.add(query1);
Expand All @@ -106,6 +135,9 @@ public static Query and(Query query1, Query query2, Query... additionalQueries)
return new And(queries);
}

/**
* Create an {@link And} for the given {@link Query}s.
*/
public static Query and(Query query1, Query query2, Collection<Query> additionalQueries) {
var queries = new ArrayList<Query>(2 + additionalQueries.size());
queries.add(query1);
Expand All @@ -119,6 +151,9 @@ public static Query or(Query query1, Query query2) {
return new Or(queries);
}

/**
* Create an {@link Or} for the given {@link Query}s.
*/
public static Query or(Query query1, Query query2, Query... additionalQueries) {
var queries = new ArrayList<Query>(2 + additionalQueries.length);
queries.add(query1);
Expand All @@ -127,6 +162,9 @@ public static Query or(Query query1, Query query2, Query... additionalQueries) {
return new Or(queries);
}

/**
* Create an {@link Or} for the given {@link Query}s.
*/
public static Query or(Query query1, Query query2, Collection<Query> additionalQueries) {
var queries = new ArrayList<Query>(2 + additionalQueries.size());
queries.add(query1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package run.halo.app.extension.index.query;

import java.util.List;
import java.util.NavigableSet;
import org.springframework.data.domain.Sort;
import run.halo.app.extension.Metadata;
import run.halo.app.extension.index.IndexSpec;

Expand Down Expand Up @@ -37,14 +39,21 @@ public interface QueryIndexView {
NavigableSet<String> getAllValuesForField(String fieldName);

/**
* Gets all object ids for a given field name.
* Gets all object ids for a given field name without null cells.
*
* @param fieldName the field name
* @return all indexed object ids for the given field name
* @throws IllegalArgumentException if the field name is not indexed
*/
NavigableSet<String> getAllIdsForField(String fieldName);

/**
* Gets all object ids in this view.
*
* @return all object ids in this view
*/
NavigableSet<String> getAllIds();

NavigableSet<String> findIdsForFieldValueEqual(String fieldName1, String fieldName2);

NavigableSet<String> findIdsForFieldValueGreaterThan(String fieldName1, String fieldName2,
Expand All @@ -53,5 +62,7 @@ NavigableSet<String> findIdsForFieldValueGreaterThan(String fieldName1, String f
NavigableSet<String> findIdsForFieldValueLessThan(String fieldName1, String fieldName2,
boolean orEqual);

void removeAllFieldValuesByIdNotIn(NavigableSet<String> ids);
void removeByIdNotIn(NavigableSet<String> ids);

List<String> sortBy(Sort sort);
}
Loading
Loading