2023-10-13 09:43:27 +00:00
|
|
|
package change
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2023-10-16 08:50:19 +00:00
|
|
|
|
2023-10-13 09:43:27 +00:00
|
|
|
"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
|
|
|
|
}
|