mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-07 20:45:53 +08:00
feat: unified writing/reading table
These changes table reading/writing to single read/write operation, and layout to machine byteorder, so db file will be unsupported with wrong byteorder.
This commit is contained in:
parent
d620fce1ae
commit
4da6584f10
@ -12,8 +12,8 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
sha1Size = 20 // md5 sha1
|
sha1Size = 20 // md5 sha1
|
||||||
tableSize = (4096 - 1) / int(unsafe.Sizeof(item{}))
|
tableSize = (2048 - 1) / int(unsafe.Sizeof(item{}))
|
||||||
cacheSlots = 23 // prime
|
cacheSlots = 13 // prime
|
||||||
superSize = int(unsafe.Sizeof(super{}))
|
superSize = int(unsafe.Sizeof(super{}))
|
||||||
tableStructSize = int(unsafe.Sizeof(table{}))
|
tableStructSize = int(unsafe.Sizeof(table{}))
|
||||||
)
|
)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package btree
|
package btree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"io"
|
"io"
|
||||||
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,119 +47,63 @@ func resetsha1(sha1 *byte) {
|
|||||||
|
|
||||||
// reading table
|
// reading table
|
||||||
|
|
||||||
func read64(r io.Reader) (int64, error) {
|
|
||||||
var b = make([]byte, 8)
|
|
||||||
_, err := r.Read(b)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return int64(binary.LittleEndian.Uint64(b)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func read32(r io.Reader) (int32, error) {
|
func read32(r io.Reader) (int32, error) {
|
||||||
var b = make([]byte, 4)
|
var b = make([]byte, 4)
|
||||||
_, err := r.Read(b)
|
_, err := r.Read(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return int32(binary.LittleEndian.Uint32(b)), nil
|
return *(*int32)(unsafe.Pointer(&b[0])), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readTable(r io.Reader, t *table) error {
|
func readTable(r io.Reader, t *table) error {
|
||||||
for i := 0; i < tableSize; i++ {
|
buf := make([]byte, tableStructSize)
|
||||||
err := readItem(r, &t.items[i])
|
_, err := r.Read(buf)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch unsafe.Sizeof(0) {
|
|
||||||
case 8:
|
|
||||||
i, err := read64(r)
|
|
||||||
t.size = int(i)
|
|
||||||
return err
|
|
||||||
case 4:
|
|
||||||
i, err := read32(r)
|
|
||||||
t.size = int(i)
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func readItem(r io.Reader, i *item) error {
|
|
||||||
_, err := r.Read(i.sha1[:])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.offset, err = read64(r)
|
*t = *(*table)(unsafe.Pointer(&buf[0]))
|
||||||
if err != nil {
|
return nil
|
||||||
return err
|
|
||||||
}
|
|
||||||
i.child, err = read64(r)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSuper(r io.Reader, s *super) error {
|
func readSuper(r io.Reader, s *super) error {
|
||||||
var err error
|
buf := make([]byte, superSize)
|
||||||
if s.top, err = read64(r); err != nil {
|
_, err := r.Read(buf)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if s.freeTop, err = read64(r); err != nil {
|
*s = *(*super)(unsafe.Pointer(&buf[0]))
|
||||||
return err
|
return nil
|
||||||
}
|
|
||||||
s.alloc, err = read64(r)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write table
|
// write table
|
||||||
|
|
||||||
func write64(w io.Writer, i int64) error {
|
func write32(w io.Writer, t int32) error {
|
||||||
var b = make([]byte, 8)
|
var p []byte
|
||||||
binary.LittleEndian.PutUint64(b, uint64(i))
|
ph := (*reflect.SliceHeader)(unsafe.Pointer(&p))
|
||||||
_, err := w.Write(b)
|
ph.Data = uintptr(unsafe.Pointer(&t))
|
||||||
return err
|
ph.Len = 4
|
||||||
}
|
ph.Cap = 4
|
||||||
|
_, err := w.Write(p)
|
||||||
func write32(w io.Writer, i int32) error {
|
|
||||||
var b = make([]byte, 4)
|
|
||||||
binary.LittleEndian.PutUint32(b, uint32(i))
|
|
||||||
_, err := w.Write(b)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTable(w io.Writer, t *table) error {
|
func writeTable(w io.Writer, t *table) error {
|
||||||
for i := 0; i < tableSize; i++ {
|
var p []byte
|
||||||
err := writeItem(w, &t.items[i])
|
ph := (*reflect.SliceHeader)(unsafe.Pointer(&p))
|
||||||
if err != nil {
|
ph.Data = uintptr(unsafe.Pointer(t))
|
||||||
return err
|
ph.Len = tableStructSize
|
||||||
}
|
ph.Cap = tableStructSize
|
||||||
}
|
_, err := w.Write(p)
|
||||||
switch unsafe.Sizeof(0) {
|
return err
|
||||||
case 8:
|
|
||||||
return write64(w, int64(t.size))
|
|
||||||
case 4:
|
|
||||||
return write32(w, int32(t.size))
|
|
||||||
default:
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeItem(w io.Writer, i *item) error {
|
|
||||||
if _, err := w.Write(i.sha1[:]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := write64(w, i.offset); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return write64(w, i.child)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeSuper(w io.Writer, s *super) error {
|
func writeSuper(w io.Writer, s *super) error {
|
||||||
if err := write64(w, s.top); err != nil {
|
var p []byte
|
||||||
return err
|
ph := (*reflect.SliceHeader)(unsafe.Pointer(&p))
|
||||||
}
|
ph.Data = uintptr(unsafe.Pointer(s))
|
||||||
if err := write64(w, s.freeTop); err != nil {
|
ph.Len = superSize
|
||||||
return err
|
ph.Cap = superSize
|
||||||
}
|
_, err := w.Write(p)
|
||||||
return write64(w, s.alloc)
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user