jldb/mdb/change/change.go

100 lines
1.8 KiB
Go

package change
import (
"io"
"git.crumpington.com/public/jldb/lib/errs"
)
// ----------------------------------------------------------------------------
// Change
// ----------------------------------------------------------------------------
// The Change type encodes a change (store / delete) to be applied to a
// pagefile.
type Change struct {
CollectionID uint64
ItemID uint64
Store bool
Data []byte
WritePageIDs []uint64
ClearPageIDs []uint64
}
func (ch Change) writeTo(w io.Writer) error {
dataSize := int64(len(ch.Data))
if !ch.Store {
dataSize = -1
}
err := writeBin(w,
ch.CollectionID,
ch.ItemID,
dataSize,
uint64(len(ch.WritePageIDs)),
uint64(len(ch.ClearPageIDs)),
ch.WritePageIDs,
ch.ClearPageIDs)
if err != nil {
return err
}
if ch.Store {
if _, err := w.Write(ch.Data); err != nil {
return errs.IO.WithErr(err)
}
}
return nil
}
func (ch *Change) readFrom(r io.Reader) error {
var pageCount, clearCount uint64
var dataSize int64
err := readBin(r,
&ch.CollectionID,
&ch.ItemID,
&dataSize,
&pageCount,
&clearCount)
if err != nil {
return err
}
if uint64(cap(ch.WritePageIDs)) < pageCount {
ch.WritePageIDs = make([]uint64, pageCount)
}
ch.WritePageIDs = ch.WritePageIDs[:pageCount]
if uint64(cap(ch.ClearPageIDs)) < clearCount {
ch.ClearPageIDs = make([]uint64, clearCount)
}
ch.ClearPageIDs = ch.ClearPageIDs[:clearCount]
if err = readBin(r, ch.WritePageIDs); err != nil {
return err
}
if err = readBin(r, ch.ClearPageIDs); err != nil {
return err
}
ch.Store = dataSize != -1
if ch.Store {
if int64(cap(ch.Data)) < dataSize {
ch.Data = make([]byte, dataSize)
}
ch.Data = ch.Data[:dataSize]
if _, err := r.Read(ch.Data); err != nil {
return errs.IO.WithErr(err)
}
} else {
ch.Data = ch.Data[:0]
}
return nil
}