reuse buffers for inode/attr walks

This commit is contained in:
Ben McClelland
2020-05-09 16:54:43 -07:00
parent f8124219c2
commit f7aaabaf98

View File

@@ -36,6 +36,7 @@ type Query struct {
index uint8 index uint8
batch uint32 batch uint32
fsfd *os.File fsfd *os.File
buf []byte
} }
// Time represents a time value in seconds and nanoseconds // Time represents a time value in seconds and nanoseconds
@@ -61,6 +62,8 @@ func NewQuery(f *os.File, opts ...Option) *Query {
opt(q) opt(q)
} }
q.buf = make([]byte, int(unsafe.Sizeof(InodesEntry{}))*int(q.batch))
return q return q
} }
@@ -94,11 +97,10 @@ func WithBatchSize(size uint32) Option {
// Next gets the next batch of inodes // Next gets the next batch of inodes
func (q *Query) Next() ([]InodesEntry, error) { func (q *Query) Next() ([]InodesEntry, error) {
buf := make([]byte, int(unsafe.Sizeof(InodesEntry{}))*int(q.batch))
query := queryInodes{ query := queryInodes{
First: q.first, First: q.first,
Last: q.last, Last: q.last,
Entries_ptr: uint64(uintptr(unsafe.Pointer(&buf[0]))), Entries_ptr: uint64(uintptr(unsafe.Pointer(&q.buf[0]))),
Nr_entries: q.batch, Nr_entries: q.batch,
Index: q.index, Index: q.index,
} }
@@ -112,7 +114,7 @@ func (q *Query) Next() ([]InodesEntry, error) {
return nil, nil return nil, nil
} }
rbuf := bytes.NewReader(buf) rbuf := bytes.NewReader(q.buf)
var inodes []InodesEntry var inodes []InodesEntry
var e InodesEntry var e InodesEntry
@@ -321,6 +323,7 @@ type Waiters struct {
iblock uint64 iblock uint64
batch uint16 batch uint16
fsfd *os.File fsfd *os.File
buf []byte
} }
// NewWaiters creates a new scoutfs Waiters // NewWaiters creates a new scoutfs Waiters
@@ -337,6 +340,8 @@ func NewWaiters(f *os.File, opts ...WOption) *Waiters {
opt(w) opt(w)
} }
w.buf = make([]byte, int(unsafe.Sizeof(DataWaitingEntry{}))*int(w.batch))
return w return w
} }
@@ -352,11 +357,10 @@ func WithWaitersCount(size uint16) WOption {
// Next gets the next batch of data waiters, returns nil, nil if no waiters // Next gets the next batch of data waiters, returns nil, nil if no waiters
func (w *Waiters) Next() ([]DataWaitingEntry, error) { func (w *Waiters) Next() ([]DataWaitingEntry, error) {
buf := make([]byte, int(unsafe.Sizeof(DataWaitingEntry{}))*int(w.batch))
dataWaiting := dataWaiting{ dataWaiting := dataWaiting{
After_ino: w.ino, After_ino: w.ino,
After_iblock: w.iblock, After_iblock: w.iblock,
Ents_ptr: uint64(uintptr(unsafe.Pointer(&buf[0]))), Ents_ptr: uint64(uintptr(unsafe.Pointer(&w.buf[0]))),
Ents_nr: w.batch, Ents_nr: w.batch,
} }
@@ -369,7 +373,7 @@ func (w *Waiters) Next() ([]DataWaitingEntry, error) {
return nil, nil return nil, nil
} }
rbuf := bytes.NewReader(buf) rbuf := bytes.NewReader(w.buf)
var inodes []DataWaitingEntry var inodes []DataWaitingEntry
var e DataWaitingEntry var e DataWaitingEntry
@@ -400,6 +404,7 @@ type XattrQuery struct {
batch uint32 batch uint32
key string key string
fsfd *os.File fsfd *os.File
buf []byte
} }
// NewXattrQuery creates a new scoutfs Xattr Query // NewXattrQuery creates a new scoutfs Xattr Query
@@ -419,6 +424,8 @@ func NewXattrQuery(f *os.File, key string, opts ...XOption) *XattrQuery {
opt(q) opt(q)
} }
q.buf = make([]byte, 8*int(q.batch))
return q return q
} }
@@ -441,12 +448,11 @@ func WithXStartIno(ino uint64) XOption {
// Next gets the next batch of inodes // Next gets the next batch of inodes
func (q *XattrQuery) Next() ([]uint64, error) { func (q *XattrQuery) Next() ([]uint64, error) {
buf := make([]byte, 8*int(q.batch))
name := []byte(q.key) name := []byte(q.key)
query := findXattrs{ query := findXattrs{
Next_ino: q.next, Next_ino: q.next,
Name_ptr: uint64(uintptr(unsafe.Pointer(&name[0]))), Name_ptr: uint64(uintptr(unsafe.Pointer(&name[0]))),
Inodes_ptr: uint64(uintptr(unsafe.Pointer(&buf[0]))), Inodes_ptr: uint64(uintptr(unsafe.Pointer(&q.buf[0]))),
Name_bytes: uint16(len(name)), Name_bytes: uint16(len(name)),
Nr_inodes: uint16(q.batch), Nr_inodes: uint16(q.batch),
} }
@@ -460,7 +466,7 @@ func (q *XattrQuery) Next() ([]uint64, error) {
return nil, nil return nil, nil
} }
rbuf := bytes.NewReader(buf) rbuf := bytes.NewReader(q.buf)
var inodes []uint64 var inodes []uint64
var e uint64 var e uint64
@@ -483,6 +489,7 @@ func (q *XattrQuery) Next() ([]uint64, error) {
type ListXattrHidden struct { type ListXattrHidden struct {
lxr *listXattrHidden lxr *listXattrHidden
f *os.File f *os.File
buf []byte
} }
// NewListXattrHidden will list all scoutfs xattrs (including hidden) for file // NewListXattrHidden will list all scoutfs xattrs (including hidden) for file
@@ -490,14 +497,14 @@ func NewListXattrHidden(f *os.File) *ListXattrHidden {
return &ListXattrHidden{ return &ListXattrHidden{
f: f, f: f,
lxr: &listXattrHidden{}, lxr: &listXattrHidden{},
buf: make([]byte, 256*1024),
} }
} }
// Next gets next set of results, complete when string slice is nil // Next gets next set of results, complete when string slice is nil
func (l *ListXattrHidden) Next() ([]string, error) { func (l *ListXattrHidden) Next() ([]string, error) {
l.lxr.Buf_bytes = 256 * 1024 l.lxr.Buf_bytes = 256 * 1024
buf := make([]byte, 256*1024) l.lxr.Buf_ptr = uint64(uintptr(unsafe.Pointer(&l.buf[0])))
l.lxr.Buf_ptr = uint64(uintptr(unsafe.Pointer(&buf[0])))
n, err := scoutfsctl(l.f, IOCLISTXATTRHIDDEN, unsafe.Pointer(l.lxr)) n, err := scoutfsctl(l.f, IOCLISTXATTRHIDDEN, unsafe.Pointer(l.lxr))
if err != nil { if err != nil {
@@ -508,7 +515,7 @@ func (l *ListXattrHidden) Next() ([]string, error) {
return nil, nil return nil, nil
} }
return bufToStrings(buf[:n]), nil return bufToStrings(l.buf[:n]), nil
} }
func bufToStrings(b []byte) []string { func bufToStrings(b []byte) []string {