diff --git a/internal/btree/btree.go b/internal/btree/btree.go index 70a43a5..590df9d 100644 --- a/internal/btree/btree.go +++ b/internal/btree/btree.go @@ -12,8 +12,8 @@ import ( const ( sha1Size = 20 // md5 sha1 - tableSize = (4096 - 1) / int(unsafe.Sizeof(item{})) - cacheSlots = 23 // prime + tableSize = (2048 - 1) / int(unsafe.Sizeof(item{})) + cacheSlots = 13 // prime superSize = int(unsafe.Sizeof(super{})) tableStructSize = int(unsafe.Sizeof(table{})) ) diff --git a/internal/btree/helper.go b/internal/btree/helper.go index ad172d9..a237e55 100644 --- a/internal/btree/helper.go +++ b/internal/btree/helper.go @@ -1,8 +1,8 @@ package btree import ( - "encoding/binary" "io" + "reflect" "unsafe" ) @@ -47,119 +47,63 @@ func resetsha1(sha1 *byte) { // 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) { var b = make([]byte, 4) _, err := r.Read(b) if err != nil { 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 { - for i := 0; i < tableSize; i++ { - err := readItem(r, &t.items[i]) - 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[:]) + buf := make([]byte, tableStructSize) + _, err := r.Read(buf) if err != nil { return err } - i.offset, err = read64(r) - if err != nil { - return err - } - i.child, err = read64(r) - return err + *t = *(*table)(unsafe.Pointer(&buf[0])) + return nil } func readSuper(r io.Reader, s *super) error { - var err error - if s.top, err = read64(r); err != nil { + buf := make([]byte, superSize) + _, err := r.Read(buf) + if err != nil { return err } - if s.freeTop, err = read64(r); err != nil { - return err - } - s.alloc, err = read64(r) - return err + *s = *(*super)(unsafe.Pointer(&buf[0])) + return nil } // write table -func write64(w io.Writer, i int64) error { - var b = make([]byte, 8) - binary.LittleEndian.PutUint64(b, uint64(i)) - _, err := w.Write(b) - return err -} - -func write32(w io.Writer, i int32) error { - var b = make([]byte, 4) - binary.LittleEndian.PutUint32(b, uint32(i)) - _, err := w.Write(b) +func write32(w io.Writer, t int32) error { + var p []byte + ph := (*reflect.SliceHeader)(unsafe.Pointer(&p)) + ph.Data = uintptr(unsafe.Pointer(&t)) + ph.Len = 4 + ph.Cap = 4 + _, err := w.Write(p) return err } func writeTable(w io.Writer, t *table) error { - for i := 0; i < tableSize; i++ { - err := writeItem(w, &t.items[i]) - if err != nil { - return err - } - } - switch unsafe.Sizeof(0) { - 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) + var p []byte + ph := (*reflect.SliceHeader)(unsafe.Pointer(&p)) + ph.Data = uintptr(unsafe.Pointer(t)) + ph.Len = tableStructSize + ph.Cap = tableStructSize + _, err := w.Write(p) + return err } func writeSuper(w io.Writer, s *super) error { - if err := write64(w, s.top); err != nil { - return err - } - if err := write64(w, s.freeTop); err != nil { - return err - } - return write64(w, s.alloc) + var p []byte + ph := (*reflect.SliceHeader)(unsafe.Pointer(&p)) + ph.Data = uintptr(unsafe.Pointer(s)) + ph.Len = superSize + ph.Cap = superSize + _, err := w.Write(p) + return err }