2019-09-20 19:28:22 +00:00
|
|
|
package rlepluslazy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
)
|
|
|
|
|
|
|
|
const Version = 0
|
|
|
|
|
|
|
|
var (
|
|
|
|
ErrWrongVersion = errors.New("invalid RLE+ version")
|
|
|
|
ErrDecode = fmt.Errorf("invalid encoding for RLE+ version %d", Version)
|
|
|
|
)
|
|
|
|
|
|
|
|
type RLE struct {
|
2019-09-23 17:58:58 +00:00
|
|
|
buf []byte
|
2019-09-20 19:28:22 +00:00
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
changes []change
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
type change struct {
|
|
|
|
set bool
|
|
|
|
index uint64
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
func FromBuf(buf []byte) (*RLE, error) {
|
|
|
|
rle := &RLE{buf: buf}
|
2019-09-20 19:28:22 +00:00
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
if len(buf) > 0 && buf[0]&3 != Version {
|
|
|
|
return nil, xerrors.Errorf("could not create RLE+ for a buffer: %w", ErrWrongVersion)
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
return rle, nil
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
func (rle *RLE) RunIterator() (RunIterator, error) {
|
|
|
|
return DecodeRLE(rle.buf)
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
func (rle *RLE) Set(index uint64) {
|
|
|
|
rle.changes = append(rle.changes, change{set: true, index: index})
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-23 17:58:58 +00:00
|
|
|
func (rle *RLE) Clear(index uint64) {
|
|
|
|
rle.changes = append(rle.changes, change{set: false, index: index})
|
2019-09-20 19:28:22 +00:00
|
|
|
}
|