Solving the challenge 0105

This commit is contained in:
2026-08-10 16:30:41 +02:00
parent c0460dd1e4
commit b45b8dd14c
2 changed files with 60 additions and 3 deletions
+48 -2
View File
@@ -1,20 +1,66 @@
package db0105 package db0105
import ( import (
"encoding/binary"
"errors" "errors"
"hash/crc32"
"io" "io"
) )
type Entry struct { type Entry struct {
crc32 []byte
key []byte key []byte
val []byte val []byte
deleted bool deleted bool
} }
func (ent *Entry) Encode() []byte func (ent *Entry) Encode() []byte {
data := make([]byte, 4+4+4+1+len(ent.key)+len(ent.val))
binary.LittleEndian.PutUint32(data[4:8], uint32(len(ent.key)))
copy(data[13:], ent.key)
if ent.deleted {
data[12] = 1
} else {
binary.LittleEndian.PutUint32(data[8:12], uint32(len(ent.val)))
copy(data[13+len(ent.key):], ent.val)
}
checksum := crc32.ChecksumIEEE(data[4:])
binary.LittleEndian.PutUint32(data[0:4], checksum)
return data
}
var ErrBadSum = errors.New("bad checksum") var ErrBadSum = errors.New("bad checksum")
func (ent *Entry) Decode(r io.Reader) error func (ent *Entry) Decode(r io.Reader) error {
var header [13]byte
if _, err := io.ReadFull(r, header[:]); err != nil {
return err
}
klen := int(binary.LittleEndian.Uint32(header[4:8]))
vlen := int(binary.LittleEndian.Uint32(header[8:12]))
deleted := header[12]
data := make([]byte, klen+vlen)
if _, err := io.ReadFull(r, data); err != nil {
return err
}
checksum := crc32.NewIEEE()
checksum.Write(header[4:])
checksum.Write(data)
if checksum.Sum32() != binary.LittleEndian.Uint32(header[0:4]) {
return ErrBadSum
}
ent.key = data[:klen]
if deleted != 0 {
ent.deleted = true
} else {
ent.deleted = false
ent.val = data[klen:]
}
return nil
}
// QzBQWVJJOUhU https://trialofcode.org/ // QzBQWVJJOUhU https://trialofcode.org/
+12 -1
View File
@@ -1,6 +1,7 @@
package db0105 package db0105
import ( import (
"io"
"os" "os"
) )
@@ -25,6 +26,16 @@ func (log *Log) Write(ent *Entry) error {
return log.fp.Sync() // fsync return log.fp.Sync() // fsync
} }
func (log *Log) Read(ent *Entry) (eof bool, err error) func (log *Log) Read(ent *Entry) (eof bool, err error) {
err = ent.Decode(log.fp)
if err == io.EOF || err == io.ErrUnexpectedEOF || err == ErrBadSum {
return true, nil
} else if err != nil {
return false, err
} else {
return false, nil
}
}
// QzBQWVJJOUhU https://trialofcode.org/ // QzBQWVJJOUhU https://trialofcode.org/