github.com/m3db/m3@v1.5.0/src/dbnode/digest/writer.go (about)

     1  // Copyright (c) 2016 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package digest
    22  
    23  import (
    24  	"bufio"
    25  	"io"
    26  	"os"
    27  )
    28  
    29  // FdWithDigestWriter provides a buffered writer for writing to the underlying file.
    30  type FdWithDigestWriter interface {
    31  	FdWithDigest
    32  	io.Writer
    33  
    34  	Flush() error
    35  }
    36  
    37  type fdWithDigestWriter struct {
    38  	FdWithDigest
    39  	writer *bufio.Writer
    40  }
    41  
    42  // NewFdWithDigestWriter creates a new FdWithDigestWriter.
    43  func NewFdWithDigestWriter(bufferSize int) FdWithDigestWriter {
    44  	return &fdWithDigestWriter{
    45  		FdWithDigest: newFdWithDigest(),
    46  		writer:       bufio.NewWriterSize(nil, bufferSize),
    47  	}
    48  }
    49  
    50  func (w *fdWithDigestWriter) Reset(fd *os.File) {
    51  	w.FdWithDigest.Reset(fd)
    52  	w.writer.Reset(fd)
    53  }
    54  
    55  // Write bytes to the underlying file.
    56  func (w *fdWithDigestWriter) Write(b []byte) (int, error) {
    57  	written, err := w.writer.Write(b)
    58  	if err != nil {
    59  		return 0, err
    60  	}
    61  	if _, err := w.FdWithDigest.Digest().Write(b); err != nil {
    62  		return 0, err
    63  	}
    64  	return written, nil
    65  }
    66  
    67  // Close flushes what's remaining in the buffered writer and closes
    68  // the underlying file.
    69  func (w *fdWithDigestWriter) Close() error {
    70  	if err := w.writer.Flush(); err != nil {
    71  		return err
    72  	}
    73  	return w.FdWithDigest.Close()
    74  }
    75  
    76  // Flush flushes what's remaining in the buffered writes.
    77  func (w *fdWithDigestWriter) Flush() error {
    78  	return w.writer.Flush()
    79  }
    80  
    81  // FdWithDigestContentsWriter provides additional functionality of writing a digest to the underlying file.
    82  type FdWithDigestContentsWriter interface {
    83  	FdWithDigestWriter
    84  
    85  	// WriteDigests writes a list of digests to the underlying file.
    86  	WriteDigests(digests ...uint32) error
    87  }
    88  
    89  type fdWithDigestContentsWriter struct {
    90  	FdWithDigestWriter
    91  
    92  	digestBuf Buffer
    93  }
    94  
    95  // NewFdWithDigestContentsWriter creates a new FdWithDigestContentsWriter.
    96  func NewFdWithDigestContentsWriter(bufferSize int) FdWithDigestContentsWriter {
    97  	return &fdWithDigestContentsWriter{
    98  		FdWithDigestWriter: NewFdWithDigestWriter(bufferSize),
    99  		digestBuf:          NewBuffer(),
   100  	}
   101  }
   102  
   103  func (w *fdWithDigestContentsWriter) WriteDigests(digests ...uint32) error {
   104  	for _, digest := range digests {
   105  		w.digestBuf.WriteDigest(digest)
   106  		if _, err := w.Write(w.digestBuf); err != nil {
   107  			return err
   108  		}
   109  	}
   110  	return nil
   111  }