Permalink
Switch branches/tags
v2.2.0-alpha.00000000 v2.1.0-beta.20181015 v2.1.0-beta.20181008 v2.1.0-beta.20181001 v2.1.0-beta.20180924 v2.1.0-beta.20180917 v2.1.0-beta.20180910 v2.1.0-beta.20180904 v2.1.0-beta.20180827 v2.1.0-alpha.20180730 v2.1.0-alpha.20180702 v2.1.0-alpha.20180604 v2.1.0-alpha.20180507 v2.1.0-alpha.20180416 v2.1.0-alpha.00000000 v2.0.6 v2.0.6-rc.1 v2.0.5 v2.0.4 v2.0.3 v2.0.2 v2.0.1 v2.0.0 v2.0-rc.1 v2.0-beta.20180326 v2.0-beta.20180319 v2.0-beta.20180312 v2.0-beta.20180305 v2.0-alpha.20180212 v2.0-alpha.20180129 v2.0-alpha.20180122 v2.0-alpha.20180116 v2.0-alpha.20171218 v2.0-alpha.20171218-plus-left-join-fix v1.2-alpha.20171211 v1.2-alpha.20171204 v1.2-alpha.20171113 v1.2-alpha.20171026 v1.2-alpha.20170901 v1.1.9 v1.1.9-rc.1 v1.1.8 v1.1.7 v1.1.6 v1.1.5 v1.1.4 v1.1.3 v1.1.2 v1.1.1 v1.1.0 v1.1.0-rc.1 v1.1-beta.20170928 v1.1-beta.20170921 v1.1-beta.20170907 v1.1-alpha.20170817 v1.1-alpha.20170810 v1.1-alpha.20170803 v1.1-alpha.20170720 v1.1-alpha.20170713 v1.1-alpha.20170629 v1.1-alpha.20170622 v1.1-alpha.20170608 v1.1-alpha.20170601 v1.0.7 v1.0.6 v1.0.5 v1.0.4 v1.0.3 v1.0.2 v1.0.1 v1.0 v1.0-rc.3 v1.0-rc.2 v1.0-rc.1 v0.1-alpha beta-20170420 beta-20170413 beta-20170406 beta-20170330 beta-20170323 beta-20170309 beta-20170223 beta-20170216 beta-20170209 beta-20170126 beta-20170112 beta-20170105 beta-20161215 beta-20161208 beta-20161201 beta-20161110 beta-20161103 beta-20161027 beta-20161013 beta-20161006 beta-20160929 beta-20160915 beta-20160908 beta-20160829 beta-20160728
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
127 lines (113 sloc) 3.51 KB
// Copyright 2018 The Cockroach Authors.
//
// 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
//
// 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 constraint
import (
"fmt"
"strings"
"github.com/cockroachdb/cockroach/pkg/sql/opt"
)
// Columns identifies the columns which correspond to the values in a Key (and
// consequently the columns of a Span or Constraint).
//
// The columns have directions; a descending column inverts the order of the
// values on that column (in other words, inverts the result of any Datum
// comparisons on that column).
type Columns struct {
// firstCol holds the first column id and otherCols hold any ids beyond the
// first. These are separated in order to optimize for the common case of a
// single-column constraint.
firstCol opt.OrderingColumn
otherCols []opt.OrderingColumn
}
// Init initializes a Columns structure.
func (c *Columns) Init(cols []opt.OrderingColumn) {
c.firstCol = cols[0]
c.otherCols = cols[1:]
}
// InitSingle is a more efficient version of Init for the common case of a
// single column.
func (c *Columns) InitSingle(col opt.OrderingColumn) {
c.firstCol = col
c.otherCols = nil
}
var _ = (*Columns).InitSingle
// Count returns the number of constrained columns (always at least one).
func (c *Columns) Count() int {
// There's always at least one column.
return 1 + len(c.otherCols)
}
// Get returns the nth column and direction. Together with the
// Count method, Get allows iteration over the list of constrained
// columns (since there is no method to return a slice of columns).
func (c *Columns) Get(nth int) opt.OrderingColumn {
// There's always at least one column.
if nth == 0 {
return c.firstCol
}
return c.otherCols[nth-1]
}
// Equals returns true if the two lists of columns are identical.
func (c *Columns) Equals(other *Columns) bool {
n := c.Count()
if n != other.Count() {
return false
}
if c.firstCol != other.firstCol {
return false
}
// Fast path for when the two share the same slice.
if n == 1 || &c.otherCols[0] == &other.otherCols[0] {
return true
}
// Hint for the compiler to eliminate bounds check inside the loop.
tmp := other.otherCols[:len(c.otherCols)]
for i, v := range c.otherCols {
if v != tmp[i] {
return false
}
}
return true
}
// IsStrictSuffixOf returns true if the columns in c are a strict suffix of the
// columns in other.
func (c *Columns) IsStrictSuffixOf(other *Columns) bool {
offset := other.Count() - c.Count()
if offset <= 0 {
return false
}
if c.firstCol != other.otherCols[offset-1] {
return false
}
// Fast path when the slices are aliased.
if len(c.otherCols) == 0 || &c.otherCols[0] == &other.otherCols[offset] {
return true
}
cmpCols := other.otherCols[offset:]
// Hint for the compiler to eliminate the bound check inside the loop.
cmpCols = cmpCols[:len(c.otherCols)]
for i, v := range c.otherCols {
if v != cmpCols[i] {
return false
}
}
return true
}
func (c Columns) String() string {
var b strings.Builder
for i := 0; i < c.Count(); i++ {
b.WriteRune('/')
b.WriteString(fmt.Sprintf("%d", c.Get(i)))
}
return b.String()
}