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.
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.appengine.api.datastore;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.apphosting.datastore.DatastoreV3Pb;
import com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter;
import com.google.apphosting.datastore.DatastoreV3Pb.RegionPoint;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Simulates the filter matching process used in the datastore for a single property name.
*
*
The true behavior of the datastore becomes extremely strange for multi-valued properties
* especially when there are inequality and equality filters on the same property. Here is the
* current logic that governs filtering:
*
*
All inequality filters are merged together into a range so that: a > 1 && a <=3 && a >=2
* becomes "There exists an x such that x is an element of a and 2 <= x <= 3"
*
*
All equality filters are handled independently so: a == 1 && a == 4 becomes "For all x in [1,
* 4] there x is an element of a"
*
*
When there are both equality and inequality filters 'a' must meet both requirements.
*
*
For example consider: a < 0 && a == 4
*
*
This may seem like a query with this filter should always return an empty result set, but this
* is actually not the case when 'a' has multiple values. This is currently planned in the datastore
* as a composite index scan on the index (a, a) where the first 'a' is set to 4 and the second 'a'
* has 'a < 0' imposed on it.
*
*
so that the value: a = [-1, 4, 2] will produces the following index data: -1, -1 -1, 2 -1, 4
* 2, -1 2, 2 2, 4 4, -1 4, 2 4, 4
*
*
the a = 4 is applied first so we restrict our scan of the index to: 4, -1 4, 2 4, 4
*
*
then a < 0 is applied to restrict our scan further to: 4, -1
*
*
thus a = [-1, 4, 2] matches our query.
*
*
It is also important to note that 'a < 0 && a > 1' will always return no results as this is
* converted into '1 < a < 0' before being applied.
*
*/
class FilterMatcher {
public static final FilterMatcher MATCH_ALL =
new FilterMatcher() {
@Override
public void addFilter(Filter filter) {
throw new UnsupportedOperationException("FilterMatcher.MATCH_ALL is immutable");
}
@Override
public boolean matches(List> values) {
return true;
}
@Override
boolean matchesRange(Comparable