github.com/blong14/gache@v0.0.0-20240124023949-89416fd8bbfa/internal/db/wal/file.go (about)

     1  package wal
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"os"
     7  	"sync"
     8  
     9  	garena "github.com/blong14/gache/internal/arena"
    10  	gfile "github.com/blong14/gache/internal/io/file"
    11  )
    12  
    13  type WAL struct {
    14  	mtx sync.Mutex
    15  	buf *bufio.Writer
    16  }
    17  
    18  func New(f *os.File) *WAL {
    19  	s, err := f.Stat()
    20  	if err != nil {
    21  		panic(err)
    22  	}
    23  	size := s.Size()
    24  	if size == 0 {
    25  		buf := bytes.NewBuffer(nil)
    26  		buf.Write(gfile.DatFileHeader(f.Name()))
    27  		_, err = f.Write(buf.Bytes())
    28  		if err != nil {
    29  			panic(err)
    30  		}
    31  	}
    32  	return &WAL{
    33  		buf: bufio.NewWriter(f),
    34  	}
    35  }
    36  
    37  var byteArena = make(garena.ByteArena, 0)
    38  
    39  func (ss *WAL) Set(k, v []byte) error {
    40  	klen := len(k)
    41  	vlen := len(v)
    42  	encoded := byteArena.Allocate(klen + vlen + 1)
    43  	encoded[0] = byte(klen)
    44  	copy(encoded[1:klen+1], k)
    45  	copy(encoded[klen+1:], v)
    46  	row, err := gfile.EncodeBlock(encoded)
    47  	if err != nil {
    48  		return err
    49  	}
    50  	ss.mtx.Lock()
    51  	_, _ = ss.buf.Write(row)
    52  	_ = ss.buf.Flush()
    53  	ss.mtx.Unlock()
    54  	return nil
    55  }