github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/store/nbs/no_conjoin_bs_persister.go (about)

     1  // Copyright 2023 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 nbs
    16  
    17  import (
    18  	"bytes"
    19  	"context"
    20  	"fmt"
    21  	"io"
    22  	"time"
    23  
    24  	"github.com/fatih/color"
    25  	"golang.org/x/sync/errgroup"
    26  
    27  	"github.com/dolthub/dolt/go/store/blobstore"
    28  	"github.com/dolthub/dolt/go/store/chunks"
    29  	"github.com/dolthub/dolt/go/store/hash"
    30  )
    31  
    32  type noConjoinBlobstorePersister struct {
    33  	bs        blobstore.Blobstore
    34  	blockSize uint64
    35  	q         MemoryQuotaProvider
    36  }
    37  
    38  var _ tablePersister = &noConjoinBlobstorePersister{}
    39  var _ tableFilePersister = &noConjoinBlobstorePersister{}
    40  
    41  // Persist makes the contents of mt durable. Chunks already present in
    42  // |haver| may be dropped in the process.
    43  func (bsp *noConjoinBlobstorePersister) Persist(ctx context.Context, mt *memTable, haver chunkReader, stats *Stats) (chunkSource, error) {
    44  	address, data, chunkCount, err := mt.write(haver, stats)
    45  	if err != nil {
    46  		return emptyChunkSource{}, err
    47  	} else if chunkCount == 0 {
    48  		return emptyChunkSource{}, nil
    49  	}
    50  	name := address.String()
    51  
    52  	eg, ectx := errgroup.WithContext(ctx)
    53  	eg.Go(func() (err error) {
    54  		fmt.Fprintf(color.Output, "Persist: bs.Put: name: %s\n", name)
    55  		_, err = bsp.bs.Put(ectx, name, int64(len(data)), bytes.NewBuffer(data))
    56  		return
    57  	})
    58  	if err = eg.Wait(); err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	rdr := &bsTableReaderAt{name, bsp.bs}
    63  	return newReaderFromIndexData(ctx, bsp.q, data, address, rdr, bsp.blockSize)
    64  }
    65  
    66  // ConjoinAll implements tablePersister.
    67  func (bsp *noConjoinBlobstorePersister) ConjoinAll(ctx context.Context, sources chunkSources, stats *Stats) (chunkSource, cleanupFunc, error) {
    68  	return emptyChunkSource{}, func() {}, fmt.Errorf("no conjoin blobstore persister does not implement ConjoinAll")
    69  }
    70  
    71  // Open a table named |name|, containing |chunkCount| chunks.
    72  func (bsp *noConjoinBlobstorePersister) Open(ctx context.Context, name hash.Hash, chunkCount uint32, stats *Stats) (chunkSource, error) {
    73  	return newBSChunkSource(ctx, bsp.bs, name, chunkCount, bsp.q, stats)
    74  }
    75  
    76  func (bsp *noConjoinBlobstorePersister) Exists(ctx context.Context, name hash.Hash, chunkCount uint32, stats *Stats) (bool, error) {
    77  	return bsp.bs.Exists(ctx, name.String())
    78  }
    79  
    80  func (bsp *noConjoinBlobstorePersister) PruneTableFiles(ctx context.Context, keeper func() []hash.Hash, t time.Time) error {
    81  	return nil
    82  }
    83  
    84  func (bsp *noConjoinBlobstorePersister) Close() error {
    85  	return nil
    86  }
    87  
    88  func (bsp *noConjoinBlobstorePersister) AccessMode() chunks.ExclusiveAccessMode {
    89  	return chunks.ExclusiveAccessMode_Shared
    90  }
    91  
    92  func (bsp *noConjoinBlobstorePersister) Path() string {
    93  	return ""
    94  }
    95  
    96  func (bsp *noConjoinBlobstorePersister) CopyTableFile(ctx context.Context, r io.Reader, name string, fileSz uint64, chunkCount uint32) error {
    97  	// sanity check file size
    98  	if fileSz < indexSize(chunkCount)+footerSize {
    99  		return fmt.Errorf("table file size %d too small for chunk count %d", fileSz, chunkCount)
   100  	}
   101  
   102  	_, err := bsp.bs.Put(ctx, name, int64(fileSz), r)
   103  	return err
   104  }