예제 #1
0
파일: file.go 프로젝트: brgmnn/syncthing
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
}
예제 #2
0
파일: pool.go 프로젝트: brgmnn/syncthing
// 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)
}
예제 #3
0
파일: pool.go 프로젝트: brgmnn/syncthing
// 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
}