vitess.io/vitess@v0.16.2/go/vt/vtgate/vindexes/numeric.go (about)

     1  /*
     2  Copyright 2019 The Vitess 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      http://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  
    17  package vindexes
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"encoding/binary"
    23  	"fmt"
    24  
    25  	"vitess.io/vitess/go/vt/vtgate/evalengine"
    26  
    27  	"vitess.io/vitess/go/sqltypes"
    28  	"vitess.io/vitess/go/vt/key"
    29  )
    30  
    31  var (
    32  	_ SingleColumn = (*Numeric)(nil)
    33  	_ Reversible   = (*Numeric)(nil)
    34  	_ Hashing      = (*Numeric)(nil)
    35  )
    36  
    37  // Numeric defines a bit-pattern mapping of a uint64 to the KeyspaceId.
    38  // It's Unique and Reversible.
    39  type Numeric struct {
    40  	name string
    41  }
    42  
    43  // NewNumeric creates a Numeric vindex.
    44  func NewNumeric(name string, _ map[string]string) (Vindex, error) {
    45  	return &Numeric{name: name}, nil
    46  }
    47  
    48  // String returns the name of the vindex.
    49  func (vind *Numeric) String() string {
    50  	return vind.name
    51  }
    52  
    53  // Cost returns the cost of this vindex as 0.
    54  func (*Numeric) Cost() int {
    55  	return 0
    56  }
    57  
    58  // IsUnique returns true since the Vindex is unique.
    59  func (*Numeric) IsUnique() bool {
    60  	return true
    61  }
    62  
    63  // NeedsVCursor satisfies the Vindex interface.
    64  func (*Numeric) NeedsVCursor() bool {
    65  	return false
    66  }
    67  
    68  // Verify returns true if ids and ksids match.
    69  func (vind *Numeric) Verify(ctx context.Context, vcursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) {
    70  	out := make([]bool, 0, len(ids))
    71  	for i, id := range ids {
    72  		ksid, err := vind.Hash(id)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  		out = append(out, bytes.Equal(ksid, ksids[i]))
    77  	}
    78  	return out, nil
    79  }
    80  
    81  // Map can map ids to key.Destination objects.
    82  func (vind *Numeric) Map(ctx context.Context, vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) {
    83  	out := make([]key.Destination, 0, len(ids))
    84  	for _, id := range ids {
    85  		ksid, err := vind.Hash(id)
    86  		if err != nil {
    87  			out = append(out, key.DestinationNone{})
    88  			continue
    89  		}
    90  		out = append(out, key.DestinationKeyspaceID(ksid))
    91  	}
    92  	return out, nil
    93  }
    94  
    95  // ReverseMap returns the associated ids for the ksids.
    96  func (*Numeric) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) {
    97  	var reverseIds = make([]sqltypes.Value, len(ksids))
    98  	for i, keyspaceID := range ksids {
    99  		if len(keyspaceID) != 8 {
   100  			return nil, fmt.Errorf("Numeric.ReverseMap: length of keyspaceId is not 8: %d", len(keyspaceID))
   101  		}
   102  		val := binary.BigEndian.Uint64(keyspaceID)
   103  		reverseIds[i] = sqltypes.NewUint64(val)
   104  	}
   105  	return reverseIds, nil
   106  }
   107  
   108  func (*Numeric) Hash(id sqltypes.Value) ([]byte, error) {
   109  	num, err := evalengine.ToUint64(id)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	var keybytes [8]byte
   114  	binary.BigEndian.PutUint64(keybytes[:], num)
   115  	return keybytes[:], nil
   116  }
   117  
   118  func init() {
   119  	Register("numeric", NewNumeric)
   120  }