github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/doltdb/durable/artifact_index.go (about)

     1  // Copyright 2022 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  package durable
    16  
    17  import (
    18  	"context"
    19  
    20  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    21  	"github.com/dolthub/dolt/go/store/hash"
    22  	"github.com/dolthub/dolt/go/store/prolly"
    23  	"github.com/dolthub/dolt/go/store/prolly/shim"
    24  	"github.com/dolthub/dolt/go/store/prolly/tree"
    25  	"github.com/dolthub/dolt/go/store/types"
    26  )
    27  
    28  type ArtifactIndex interface {
    29  	HashOf() (hash.Hash, error)
    30  	Count() (uint64, error)
    31  	Format() *types.NomsBinFormat
    32  	HasConflicts(ctx context.Context) (bool, error)
    33  	// ConflictCount returns the number of conflicts
    34  	ConflictCount(ctx context.Context) (uint64, error)
    35  	// ConstraintViolationCount returns the sum total of foreign key violations,
    36  	// unique key violations, and check constraint violations.
    37  	ConstraintViolationCount(ctx context.Context) (uint64, error)
    38  	// ClearConflicts clears all conflicts
    39  	ClearConflicts(ctx context.Context) (ArtifactIndex, error)
    40  }
    41  
    42  // RefFromArtifactIndex persists |idx| and returns the types.Ref targeting it.
    43  func RefFromArtifactIndex(ctx context.Context, vrw types.ValueReadWriter, idx ArtifactIndex) (types.Ref, error) {
    44  	switch idx.Format() {
    45  	case types.Format_LD_1:
    46  		panic("TODO")
    47  
    48  	case types.Format_DOLT:
    49  		b := shim.ValueFromArtifactMap(idx.(prollyArtifactIndex).index)
    50  		return refFromNomsValue(ctx, vrw, b)
    51  
    52  	default:
    53  		return types.Ref{}, errNbfUnknown
    54  	}
    55  }
    56  
    57  // NewEmptyArtifactIndex returns an ArtifactIndex with no artifacts.
    58  func NewEmptyArtifactIndex(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, tableSch schema.Schema) (ArtifactIndex, error) {
    59  	switch vrw.Format() {
    60  	case types.Format_LD_1:
    61  		panic("TODO")
    62  
    63  	case types.Format_DOLT:
    64  		kd := tableSch.GetKeyDescriptor()
    65  		m, err := prolly.NewArtifactMapFromTuples(ctx, ns, kd)
    66  		if err != nil {
    67  			return nil, err
    68  		}
    69  		return ArtifactIndexFromProllyMap(m), nil
    70  
    71  	default:
    72  		return nil, errNbfUnknown
    73  	}
    74  }
    75  
    76  func ArtifactIndexFromProllyMap(m prolly.ArtifactMap) ArtifactIndex {
    77  	return prollyArtifactIndex{
    78  		index: m,
    79  	}
    80  }
    81  
    82  func ProllyMapFromArtifactIndex(i ArtifactIndex) prolly.ArtifactMap {
    83  	return i.(prollyArtifactIndex).index
    84  }
    85  
    86  func artifactIndexFromRef(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, tableSch schema.Schema, r types.Ref) (ArtifactIndex, error) {
    87  	return artifactIndexFromAddr(ctx, vrw, ns, tableSch, r.TargetHash())
    88  }
    89  
    90  func artifactIndexFromAddr(ctx context.Context, vrw types.ValueReadWriter, ns tree.NodeStore, tableSch schema.Schema, addr hash.Hash) (ArtifactIndex, error) {
    91  	v, err := vrw.ReadValue(ctx, addr)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	switch vrw.Format() {
    97  	case types.Format_LD_1:
    98  		panic("TODO")
    99  
   100  	case types.Format_DOLT:
   101  		root, err := shim.NodeFromValue(v)
   102  		if err != nil {
   103  			return nil, err
   104  		}
   105  		kd := tableSch.GetKeyDescriptor()
   106  		m := prolly.NewArtifactMap(root, ns, kd)
   107  		return ArtifactIndexFromProllyMap(m), nil
   108  
   109  	default:
   110  		return nil, errNbfUnknown
   111  	}
   112  }
   113  
   114  type prollyArtifactIndex struct {
   115  	index prolly.ArtifactMap
   116  }
   117  
   118  func (i prollyArtifactIndex) HashOf() (hash.Hash, error) {
   119  	return i.index.HashOf(), nil
   120  }
   121  
   122  func (i prollyArtifactIndex) Count() (uint64, error) {
   123  	c, err := i.index.Count()
   124  	return uint64(c), err
   125  }
   126  
   127  func (i prollyArtifactIndex) Format() *types.NomsBinFormat {
   128  	return i.index.Format()
   129  }
   130  
   131  func (i prollyArtifactIndex) HasConflicts(ctx context.Context) (bool, error) {
   132  	return i.index.HasArtifactOfType(ctx, prolly.ArtifactTypeConflict)
   133  }
   134  
   135  func (i prollyArtifactIndex) ConflictCount(ctx context.Context) (uint64, error) {
   136  	return i.index.CountOfType(ctx, prolly.ArtifactTypeConflict)
   137  }
   138  
   139  func (i prollyArtifactIndex) ConstraintViolationCount(ctx context.Context) (uint64, error) {
   140  	return i.index.CountOfTypes(ctx,
   141  		prolly.ArtifactTypeForeignKeyViol,
   142  		prolly.ArtifactTypeUniqueKeyViol,
   143  		prolly.ArtifactTypeChkConsViol,
   144  		prolly.ArtifactTypeNullViol)
   145  }
   146  
   147  func (i prollyArtifactIndex) ClearConflicts(ctx context.Context) (ArtifactIndex, error) {
   148  	updated, err := i.index.ClearArtifactsOfType(ctx, prolly.ArtifactTypeConflict)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	return prollyArtifactIndex{updated}, nil
   153  }