func newFile(f *os.File, maxSize int64, pgBits uint) (*file, error) { if maxSize < 0 { panic("internal error") } pgSize := 1 << pgBits switch { case sysPage > pgSize: pgBits = uint(mathutil.Log2Uint64(uint64(sysPage))) default: pgBits = uint(mathutil.Log2Uint64(uint64(pgSize / sysPage * sysPage))) } pgSize = 1 << pgBits fi := &file{ f: f, m: fileMap{}, maxPages: int(mathutil.MinInt64( 1024, mathutil.MaxInt64(maxSize/int64(pgSize), 1)), ), pgBits: pgBits, pgMask: pgSize - 1, pgSize: pgSize, } info, err := f.Stat() if err != nil { return nil, err } if err = fi.Truncate(info.Size()); err != nil { return nil, err } return fi, nil }
// Put puts a *[]T into a pool for possible later reuse by CGet or Get. Put // panics is its argument is not of type *[]T. // // Put is safe for concurrent use by multiple goroutines. func (p *Pool) Put(b interface{}) { size := p.cap(b) if size == 0 { return } p.m[mathutil.Log2Uint64(uint64(size))].Put(b) }
// Get returns a *[]T of len size. The pointed to slice is not zeroed. Get // panics for size < 0. // // Get is safe for concurrent use by multiple goroutines. func (p *Pool) Get(size int) interface{} { var index int switch { case size < 0: panic("Pool.Get: negative size") case size == 0: return p.null case size > 1: index = mathutil.Log2Uint64(uint64(size-1)) + 1 } s := p.m[index].Get() p.setSize(s, size) return s }