Solving the challenge 0105
This commit is contained in:
+48
-2
@@ -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
@@ -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/
|
||||||
|
|||||||
Reference in New Issue
Block a user