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 }