mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-23 18:10:39 +00:00
cql3: Convert TermSlice
This commit is contained in:
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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
|
||||
*
|
||||
* http://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 org.apache.cassandra.cql3.restrictions;
|
||||
|
||||
import org.apache.cassandra.cql3.Operator;
|
||||
import org.apache.cassandra.cql3.Term;
|
||||
import org.apache.cassandra.cql3.statements.Bound;
|
||||
import org.apache.cassandra.db.index.SecondaryIndex;
|
||||
|
||||
final class TermSlice
|
||||
{
|
||||
/**
|
||||
* The slice boundaries.
|
||||
*/
|
||||
private final Term[] bounds;
|
||||
|
||||
/**
|
||||
* Specifies if a slice boundary is inclusive or not.
|
||||
*/
|
||||
private final boolean[] boundInclusive;
|
||||
|
||||
/**
|
||||
* Creates a new <code>TermSlice</code> with the specified boundaries.
|
||||
*
|
||||
* @param start the lower boundary
|
||||
* @param includeStart <code>true</code> if the lower boundary is inclusive
|
||||
* @param end the upper boundary
|
||||
* @param includeEnd <code>true</code> if the upper boundary is inclusive
|
||||
*/
|
||||
private TermSlice(Term start, boolean includeStart, Term end, boolean includeEnd)
|
||||
{
|
||||
bounds = new Term[]{start, end};
|
||||
boundInclusive = new boolean[]{includeStart, includeEnd};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>TermSlice</code> with the specified boundary.
|
||||
*
|
||||
* @param bound the boundary type
|
||||
* @param include <code>true</code> if the boundary is inclusive
|
||||
* @param term the value
|
||||
* @return a new <code>TermSlice</code> instance
|
||||
*/
|
||||
public static TermSlice newInstance(Bound bound, boolean include, Term term)
|
||||
{
|
||||
return bound.isStart() ? new TermSlice(term, include, null, false)
|
||||
: new TermSlice(null, false, term, include);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary value.
|
||||
*
|
||||
* @param bound the boundary type
|
||||
* @return the boundary value
|
||||
*/
|
||||
public Term bound(Bound bound)
|
||||
{
|
||||
return bounds[bound.idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this slice has a boundary for the specified type.
|
||||
*
|
||||
* @param b the boundary type
|
||||
* @return <code>true</code> if this slice has a boundary for the specified type, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasBound(Bound b)
|
||||
{
|
||||
return bounds[b.idx] != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this slice boundary is inclusive for the specified type.
|
||||
*
|
||||
* @param b the boundary type
|
||||
* @return <code>true</code> if this slice boundary is inclusive for the specified type,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isInclusive(Bound b)
|
||||
{
|
||||
return bounds[b.idx] == null || boundInclusive[b.idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges this slice with the specified one.
|
||||
*
|
||||
* @param otherSlice the slice to merge to
|
||||
* @return the new slice resulting from the merge
|
||||
*/
|
||||
public TermSlice merge(TermSlice otherSlice)
|
||||
{
|
||||
if (hasBound(Bound.START))
|
||||
{
|
||||
assert !otherSlice.hasBound(Bound.START);
|
||||
|
||||
return new TermSlice(bound(Bound.START),
|
||||
isInclusive(Bound.START),
|
||||
otherSlice.bound(Bound.END),
|
||||
otherSlice.isInclusive(Bound.END));
|
||||
}
|
||||
assert !otherSlice.hasBound(Bound.END);
|
||||
|
||||
return new TermSlice(otherSlice.bound(Bound.START),
|
||||
otherSlice.isInclusive(Bound.START),
|
||||
bound(Bound.END),
|
||||
isInclusive(Bound.END));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("(%s %s, %s %s)", boundInclusive[0] ? ">=" : ">",
|
||||
bounds[0],
|
||||
boundInclusive[1] ? "<=" : "<",
|
||||
bounds[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index operator corresponding to the specified boundary.
|
||||
*
|
||||
* @param b the boundary type
|
||||
* @return the index operator corresponding to the specified boundary
|
||||
*/
|
||||
public Operator getIndexOperator(Bound b)
|
||||
{
|
||||
if (b.isStart())
|
||||
return boundInclusive[b.idx] ? Operator.GTE : Operator.GT;
|
||||
|
||||
return boundInclusive[b.idx] ? Operator.LTE : Operator.LT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this <code>TermSlice</code> is supported by the specified index.
|
||||
*
|
||||
* @param index the Secondary index
|
||||
* @return <code>true</code> this type of <code>TermSlice</code> is supported by the specified index,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isSupportedBy(SecondaryIndex index)
|
||||
{
|
||||
boolean supported = false;
|
||||
|
||||
if (hasBound(Bound.START))
|
||||
supported |= isInclusive(Bound.START) ? index.supportsOperator(Operator.GTE)
|
||||
: index.supportsOperator(Operator.GT);
|
||||
if (hasBound(Bound.END))
|
||||
supported |= isInclusive(Bound.END) ? index.supportsOperator(Operator.LTE)
|
||||
: index.supportsOperator(Operator.LT);
|
||||
|
||||
return supported;
|
||||
}
|
||||
}
|
||||
152
cql3/restrictions/term_slice.hh
Normal file
152
cql3/restrictions/term_slice.hh
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015 Cloudius Systems
|
||||
*
|
||||
* Modified by Cloudius Systems
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cql3/restrictions/abstract_restriction.hh"
|
||||
#include "cql3/term.hh"
|
||||
#include "core/shared_ptr.hh"
|
||||
#include "database.hh"
|
||||
#include "to_string.hh"
|
||||
#include "exceptions/exceptions.hh"
|
||||
|
||||
namespace cql3 {
|
||||
|
||||
namespace restrictions {
|
||||
|
||||
class term_slice final {
|
||||
private:
|
||||
struct bound {
|
||||
bool inclusive;
|
||||
::shared_ptr<term> t;
|
||||
};
|
||||
bound _bounds[2];
|
||||
private:
|
||||
term_slice(::shared_ptr<term> start, bool include_start, ::shared_ptr<term> end, bool include_end)
|
||||
: _bounds{{include_start, std::move(start)}, {include_end, std::move(end)}}
|
||||
{ }
|
||||
public:
|
||||
static term_slice new_instance(statements::bound bound, bool include, ::shared_ptr<term> term) {
|
||||
if (is_start(bound)) {
|
||||
return term_slice(std::move(term), include, {}, false);
|
||||
} else {
|
||||
return term_slice({}, false, std::move(term), include);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary value.
|
||||
*
|
||||
* @param bound the boundary type
|
||||
* @return the boundary value
|
||||
*/
|
||||
::shared_ptr<term> bound(statements::bound b) const {
|
||||
return _bounds[get_idx(b)].t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this slice has a boundary for the specified type.
|
||||
*
|
||||
* @param b the boundary type
|
||||
* @return <code>true</code> if this slice has a boundary for the specified type, <code>false</code> otherwise.
|
||||
*/
|
||||
bool has_bound(statements::bound b) const {
|
||||
return bool(_bounds[get_idx(b)].t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this slice boundary is inclusive for the specified type.
|
||||
*
|
||||
* @param b the boundary type
|
||||
* @return <code>true</code> if this slice boundary is inclusive for the specified type,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
bool is_inclusive(statements::bound b) const {
|
||||
return !_bounds[get_idx(b)].t || _bounds[get_idx(b)].inclusive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges this slice with the specified one.
|
||||
*
|
||||
* @param other the slice to merge with
|
||||
*/
|
||||
void merge(const term_slice& other) {
|
||||
if (has_bound(statements::bound::START)) {
|
||||
assert(!other.has_bound(statements::bound::START));
|
||||
_bounds[get_idx(statements::bound::END)] = other._bounds[get_idx(statements::bound::END)];
|
||||
} else {
|
||||
assert(!other.has_bound(statements::bound::END));
|
||||
_bounds[get_idx(statements::bound::START)] = other._bounds[get_idx(statements::bound::START)];
|
||||
}
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const term_slice& slice) {
|
||||
static auto print_term = [] (::shared_ptr<term> t) -> sstring {
|
||||
return t ? t->to_string() : "null";
|
||||
};
|
||||
return out << sprint("(%s %s, %s %s)",
|
||||
slice._bounds[0].inclusive ? ">=" : ">", print_term(slice._bounds[0].t),
|
||||
slice._bounds[1].inclusive ? "<=" : "<", print_term(slice._bounds[1].t));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Returns the index operator corresponding to the specified boundary.
|
||||
*
|
||||
* @param b the boundary type
|
||||
* @return the index operator corresponding to the specified boundary
|
||||
*/
|
||||
public Operator getIndexOperator(statements::bound b)
|
||||
{
|
||||
if (b.isStart())
|
||||
return boundInclusive[get_idx(b)] ? Operator.GTE : Operator.GT;
|
||||
|
||||
return boundInclusive[get_idx(b)] ? Operator.LTE : Operator.LT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this <code>TermSlice</code> is supported by the specified index.
|
||||
*
|
||||
* @param index the Secondary index
|
||||
* @return <code>true</code> this type of <code>TermSlice</code> is supported by the specified index,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public bool isSupportedBy(SecondaryIndex index)
|
||||
{
|
||||
bool supported = false;
|
||||
|
||||
if (has_bound(statements::bound::START))
|
||||
supported |= isInclusive(statements::bound::START) ? index.supportsOperator(Operator.GTE)
|
||||
: index.supportsOperator(Operator.GT);
|
||||
if (has_bound(statements::bound::END))
|
||||
supported |= isInclusive(statements::bound::END) ? index.supportsOperator(Operator.LTE)
|
||||
: index.supportsOperator(Operator.LT);
|
||||
|
||||
return supported;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user