github.com/cockroachdb/pebble@v1.1.2/objstorage/objstorageprovider/vfs.go (about)

     1  // Copyright 2023 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  package objstorageprovider
     6  
     7  import (
     8  	"context"
     9  
    10  	"github.com/cockroachdb/errors"
    11  	"github.com/cockroachdb/pebble/internal/base"
    12  	"github.com/cockroachdb/pebble/objstorage"
    13  	"github.com/cockroachdb/pebble/vfs"
    14  )
    15  
    16  func (p *provider) vfsPath(fileType base.FileType, fileNum base.DiskFileNum) string {
    17  	return base.MakeFilepath(p.st.FS, p.st.FSDirName, fileType, fileNum)
    18  }
    19  
    20  func (p *provider) vfsOpenForReading(
    21  	ctx context.Context,
    22  	fileType base.FileType,
    23  	fileNum base.DiskFileNum,
    24  	opts objstorage.OpenOptions,
    25  ) (objstorage.Readable, error) {
    26  	filename := p.vfsPath(fileType, fileNum)
    27  	file, err := p.st.FS.Open(filename, vfs.RandomReadsOption)
    28  	if err != nil {
    29  		if opts.MustExist {
    30  			base.MustExist(p.st.FS, filename, p.st.Logger, err)
    31  		}
    32  		return nil, err
    33  	}
    34  	readaheadConfig := DefaultReadaheadConfig
    35  	if f := p.st.Local.ReadaheadConfigFn; f != nil {
    36  		readaheadConfig = f()
    37  	}
    38  	return newFileReadable(file, p.st.FS, readaheadConfig, filename)
    39  }
    40  
    41  func (p *provider) vfsCreate(
    42  	_ context.Context, fileType base.FileType, fileNum base.DiskFileNum,
    43  ) (objstorage.Writable, objstorage.ObjectMetadata, error) {
    44  	filename := p.vfsPath(fileType, fileNum)
    45  	file, err := p.st.FS.Create(filename)
    46  	if err != nil {
    47  		return nil, objstorage.ObjectMetadata{}, err
    48  	}
    49  	file = vfs.NewSyncingFile(file, vfs.SyncingFileOptions{
    50  		NoSyncOnClose: p.st.NoSyncOnClose,
    51  		BytesPerSync:  p.st.BytesPerSync,
    52  	})
    53  	meta := objstorage.ObjectMetadata{
    54  		DiskFileNum: fileNum,
    55  		FileType:    fileType,
    56  	}
    57  	return newFileBufferedWritable(file), meta, nil
    58  }
    59  
    60  func (p *provider) vfsRemove(fileType base.FileType, fileNum base.DiskFileNum) error {
    61  	return p.st.FSCleaner.Clean(p.st.FS, fileType, p.vfsPath(fileType, fileNum))
    62  }
    63  
    64  // vfsInit finds any local FS objects.
    65  func (p *provider) vfsInit() error {
    66  	listing := p.st.FSDirInitialListing
    67  	if listing == nil {
    68  		var err error
    69  		listing, err = p.st.FS.List(p.st.FSDirName)
    70  		if err != nil {
    71  			return errors.Wrapf(err, "pebble: could not list store directory")
    72  		}
    73  	}
    74  
    75  	for _, filename := range listing {
    76  		fileType, fileNum, ok := base.ParseFilename(p.st.FS, filename)
    77  		if ok && fileType == base.FileTypeTable {
    78  			o := objstorage.ObjectMetadata{
    79  				FileType:    fileType,
    80  				DiskFileNum: fileNum,
    81  			}
    82  			p.mu.knownObjects[o.DiskFileNum] = o
    83  		}
    84  	}
    85  	return nil
    86  }
    87  
    88  func (p *provider) vfsSync() error {
    89  	p.mu.Lock()
    90  	shouldSync := p.mu.localObjectsChanged
    91  	p.mu.localObjectsChanged = false
    92  	p.mu.Unlock()
    93  
    94  	if !shouldSync {
    95  		return nil
    96  	}
    97  	if err := p.fsDir.Sync(); err != nil {
    98  		p.mu.Lock()
    99  		defer p.mu.Unlock()
   100  		p.mu.localObjectsChanged = true
   101  		return err
   102  	}
   103  	return nil
   104  }
   105  
   106  func (p *provider) vfsSize(fileType base.FileType, fileNum base.DiskFileNum) (int64, error) {
   107  	filename := p.vfsPath(fileType, fileNum)
   108  	stat, err := p.st.FS.Stat(filename)
   109  	if err != nil {
   110  		return 0, err
   111  	}
   112  	return stat.Size(), nil
   113  }