github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/types/value.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // This file incorporates work covered by the following copyright and
    16  // permission notice:
    17  //
    18  // Copyright 2016 Attic Labs, Inc. All rights reserved.
    19  // Licensed under the Apache License, version 2.0:
    20  // http://www.apache.org/licenses/LICENSE-2.0
    21  
    22  package types
    23  
    24  import (
    25  	"bytes"
    26  	"context"
    27  
    28  	"github.com/dolthub/dolt/go/store/hash"
    29  )
    30  
    31  type ValueCallback func(v Value) error
    32  type RefCallback func(ref Ref) error
    33  type MarshalCallback func(val Value) (Value, error)
    34  
    35  var MaxPrimitiveKind int
    36  var PrimitiveKindMask []bool
    37  
    38  func init() {
    39  	for _, value := range KindToType {
    40  		if value != nil && value.isPrimitive() {
    41  			nomsKind := value.Kind()
    42  			PrimitiveTypeMap[nomsKind] = makePrimitiveType(nomsKind)
    43  		}
    44  	}
    45  	for k := range PrimitiveTypeMap {
    46  		if int(k) > MaxPrimitiveKind {
    47  			MaxPrimitiveKind = int(k)
    48  		}
    49  	}
    50  	PrimitiveKindMask = make([]bool, MaxPrimitiveKind+1)
    51  	for k := range PrimitiveTypeMap {
    52  		PrimitiveKindMask[int(k)] = true
    53  	}
    54  
    55  	maxKindInKindToType := 0
    56  	for k := range KindToType {
    57  		if int(k) > maxKindInKindToType {
    58  			maxKindInKindToType = int(k)
    59  		}
    60  	}
    61  	KindToTypeSlice = make([]Value, maxKindInKindToType+1)
    62  	for k, v := range KindToType {
    63  		KindToTypeSlice[int(k)] = v
    64  	}
    65  
    66  }
    67  
    68  // Valuable is an interface from which a Value can be retrieved.
    69  type Valuable interface {
    70  	// Kind is the NomsKind describing the kind of value this is.
    71  	Kind() NomsKind
    72  
    73  	Value(ctx context.Context) (Value, error)
    74  }
    75  
    76  type LesserValuable interface {
    77  	Valuable
    78  	// Less determines if this Noms value is less than another Noms value.
    79  	// When comparing two Noms values and both are comparable and the same type (Bool, Float or
    80  	// String) then the natural ordering is used. For other Noms values the Hash of the value is
    81  	// used. When comparing Noms values of different type the following ordering is used:
    82  	// Bool < Float < String < everything else.
    83  	Less(nbf *NomsBinFormat, other LesserValuable) (bool, error)
    84  }
    85  
    86  // Emptyable is an interface for Values which may or may not be empty
    87  type Emptyable interface {
    88  	Empty() bool
    89  }
    90  
    91  // Value is the interface all Noms values implement.
    92  type Value interface {
    93  	LesserValuable
    94  
    95  	// Equals determines if two different Noms values represents the same underlying value.
    96  	Equals(other Value) bool
    97  
    98  	// Hash is the hash of the value. All Noms values have a unique hash and if two values have the
    99  	// same hash they must be equal.
   100  	Hash(*NomsBinFormat) (hash.Hash, error)
   101  
   102  	// isPrimitive returns whether the Value is a primitive type
   103  	isPrimitive() bool
   104  
   105  	// WalkValues iterates over the immediate children of this value in the DAG, if any, not including
   106  	// Type()
   107  	WalkValues(context.Context, ValueCallback) error
   108  
   109  	// WalkRefs iterates over the refs to the underlying chunks. If this value is a collection that has been
   110  	// chunked then this will return the refs of th sub trees of the prolly-tree.
   111  	WalkRefs(*NomsBinFormat, RefCallback) error
   112  
   113  	// HumanReadableString returns a human-readable string version of this Value (not meant for re-parsing)
   114  	HumanReadableString() string
   115  
   116  	// typeOf is the internal implementation of types.TypeOf. It is not normalized
   117  	// and unions might have a single element, duplicates and be in the wrong
   118  	// order.
   119  	typeOf() (*Type, error)
   120  
   121  	// writeTo writes the encoded version of the value to a nomsWriter.
   122  	writeTo(nomsWriter, *NomsBinFormat) error
   123  
   124  	// readFrom reads the encoded version of the value from a binaryNomsReader
   125  	readFrom(*NomsBinFormat, *binaryNomsReader) (Value, error)
   126  
   127  	// skip takes in a binaryNomsReader and skips the encoded version of the value
   128  	skip(*NomsBinFormat, *binaryNomsReader)
   129  }
   130  
   131  type ValueSlice []Value
   132  
   133  func (vs ValueSlice) Equals(other ValueSlice) bool {
   134  	if len(vs) != len(other) {
   135  		return false
   136  	}
   137  
   138  	for i, v := range vs {
   139  		if !v.Equals(other[i]) {
   140  			return false
   141  		}
   142  	}
   143  
   144  	return true
   145  }
   146  
   147  func (vs ValueSlice) Contains(nbf *NomsBinFormat, v Value) bool {
   148  	for _, v := range vs {
   149  		if v.Equals(v) {
   150  			return true
   151  		}
   152  	}
   153  	return false
   154  }
   155  
   156  type ValueSort struct {
   157  	Values []Value
   158  	Nbf    *NomsBinFormat
   159  }
   160  
   161  func (vs ValueSort) Len() int      { return len(vs.Values) }
   162  func (vs ValueSort) Swap(i, j int) { vs.Values[i], vs.Values[j] = vs.Values[j], vs.Values[i] }
   163  func (vs ValueSort) Less(i, j int) (bool, error) {
   164  	return vs.Values[i].Less(vs.Nbf, vs.Values[j])
   165  }
   166  
   167  func (vs ValueSort) Equals(other ValueSort) bool {
   168  	return ValueSlice(vs.Values).Equals(ValueSlice(other.Values))
   169  }
   170  
   171  func (vs ValueSort) Contains(v Value) bool {
   172  	return ValueSlice(vs.Values).Contains(vs.Nbf, v)
   173  }
   174  
   175  type valueReadWriter interface {
   176  	valueReadWriter() ValueReadWriter
   177  }
   178  
   179  type TupleSlice []Tuple
   180  
   181  func (vs TupleSlice) Equals(other TupleSlice) bool {
   182  	if len(vs) != len(other) {
   183  		return false
   184  	}
   185  
   186  	for i, v := range vs {
   187  		if !v.Equals(other[i]) {
   188  			return false
   189  		}
   190  	}
   191  
   192  	return true
   193  }
   194  
   195  func (vs TupleSlice) Contains(nbf *NomsBinFormat, v Tuple) bool {
   196  	for _, v := range vs {
   197  		if v.Equals(v) {
   198  			return true
   199  		}
   200  	}
   201  	return false
   202  }
   203  
   204  type TupleSort struct {
   205  	Tuples []Tuple
   206  	Nbf    *NomsBinFormat
   207  }
   208  
   209  func (vs TupleSort) Len() int {
   210  	return len(vs.Tuples)
   211  }
   212  
   213  func (vs TupleSort) Swap(i, j int) {
   214  	vs.Tuples[i], vs.Tuples[j] = vs.Tuples[j], vs.Tuples[i]
   215  }
   216  
   217  func (vs TupleSort) Less(i, j int) (bool, error) {
   218  	return vs.Tuples[i].TupleLess(vs.Nbf, vs.Tuples[j])
   219  }
   220  
   221  func (vs TupleSort) Equals(other TupleSort) bool {
   222  	return TupleSlice(vs.Tuples).Equals(other.Tuples)
   223  }
   224  
   225  func (vs TupleSort) Contains(v Tuple) bool {
   226  	return TupleSlice(vs.Tuples).Contains(vs.Nbf, v)
   227  }
   228  
   229  type valueImpl struct {
   230  	vrw     ValueReadWriter
   231  	nbf     *NomsBinFormat
   232  	buff    []byte
   233  	offsets []uint32
   234  }
   235  
   236  func (v valueImpl) valueReadWriter() ValueReadWriter {
   237  	return v.vrw
   238  }
   239  
   240  func (v valueImpl) writeTo(enc nomsWriter, nbf *NomsBinFormat) error {
   241  	enc.writeRaw(v.buff)
   242  	return nil
   243  }
   244  
   245  // IsZeroValue can be used to test if a Value is the same as T{}.
   246  func (v valueImpl) IsZeroValue() bool {
   247  	return v.buff == nil
   248  }
   249  
   250  func (v valueImpl) Hash(*NomsBinFormat) (hash.Hash, error) {
   251  	return hash.Of(v.buff), nil
   252  }
   253  
   254  func (v valueImpl) decoder() valueDecoder {
   255  	return newValueDecoder(v.buff, v.vrw)
   256  }
   257  
   258  func (v valueImpl) format() *NomsBinFormat {
   259  	return v.nbf
   260  }
   261  
   262  func (v valueImpl) decoderAtOffset(offset int) valueDecoder {
   263  	return newValueDecoder(v.buff[offset:], v.vrw)
   264  }
   265  
   266  func (v valueImpl) asValueImpl() valueImpl {
   267  	return v
   268  }
   269  
   270  func (v valueImpl) Equals(other Value) bool {
   271  	if otherValueImpl, ok := other.(asValueImpl); ok {
   272  		return bytes.Equal(v.buff, otherValueImpl.asValueImpl().buff)
   273  	}
   274  	return false
   275  }
   276  
   277  func (v valueImpl) Less(nbf *NomsBinFormat, other LesserValuable) (bool, error) {
   278  	return valueLess(nbf, v, other.(Value))
   279  }
   280  
   281  func (v valueImpl) WalkRefs(nbf *NomsBinFormat, cb RefCallback) error {
   282  	w := binaryNomsWriter{make([]byte, len(v.buff)+1), 0}
   283  	err := v.writeTo(&w, nbf)
   284  
   285  	if err != nil {
   286  		return err
   287  	}
   288  
   289  	return walkRefs(w.buff[:w.offset], nbf, cb)
   290  }
   291  
   292  type asValueImpl interface {
   293  	asValueImpl() valueImpl
   294  }
   295  
   296  func (v valueImpl) Kind() NomsKind {
   297  	return NomsKind(v.buff[0])
   298  }