github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/objstorage/objstorageprovider/vfs_writable.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  	"bufio"
     9  
    10  	"github.com/cockroachdb/pebble/objstorage"
    11  	"github.com/cockroachdb/pebble/vfs"
    12  )
    13  
    14  // NewFileWritable returns a Writable that uses a file as underlying storage.
    15  func NewFileWritable(file vfs.File) objstorage.Writable {
    16  	return newFileBufferedWritable(file)
    17  }
    18  
    19  type fileBufferedWritable struct {
    20  	file vfs.File
    21  	bw   *bufio.Writer
    22  }
    23  
    24  var _ objstorage.Writable = (*fileBufferedWritable)(nil)
    25  
    26  func newFileBufferedWritable(file vfs.File) *fileBufferedWritable {
    27  	return &fileBufferedWritable{
    28  		file: file,
    29  		bw:   bufio.NewWriter(file),
    30  	}
    31  }
    32  
    33  // Write is part of the objstorage.Writable interface.
    34  func (w *fileBufferedWritable) Write(p []byte) error {
    35  	// Ignoring the length written since bufio.Writer.Write is guaranteed to
    36  	// return an error if the length written is < len(p).
    37  	_, err := w.bw.Write(p)
    38  	return err
    39  }
    40  
    41  // Finish is part of the objstorage.Writable interface.
    42  func (w *fileBufferedWritable) Finish() error {
    43  	err := w.bw.Flush()
    44  	if err == nil {
    45  		err = w.file.Sync()
    46  	}
    47  	err = firstError(err, w.file.Close())
    48  	w.bw = nil
    49  	w.file = nil
    50  	return err
    51  }
    52  
    53  // Abort is part of the objstorage.Writable interface.
    54  func (w *fileBufferedWritable) Abort() {
    55  	_ = w.file.Close()
    56  	w.bw = nil
    57  	w.file = nil
    58  }
    59  
    60  func firstError(err0, err1 error) error {
    61  	if err0 != nil {
    62  		return err0
    63  	}
    64  	return err1
    65  }