mmap_span: Avoid allocating the span slice on every use
This commit is contained in:
parent
f050bc02f7
commit
ac1afa19b8
|
@ -33,7 +33,7 @@ func main() {
|
|||
log.Print(err)
|
||||
}
|
||||
defer devZero.Close()
|
||||
var mMapSpan mmap_span.MMapSpan
|
||||
var mMapSpan *mmap_span.MMapSpan
|
||||
for _, file := range metaInfo.Info.Files {
|
||||
filename := filepath.Join(append([]string{*dirPath, metaInfo.Info.Name}, file.Path...)...)
|
||||
osFile, err := os.Open(filename)
|
||||
|
@ -53,7 +53,7 @@ func main() {
|
|||
log.Printf("file mmap has wrong size: %#v", filename)
|
||||
}
|
||||
osFile.Close()
|
||||
mMapSpan = append(mMapSpan, goMMap)
|
||||
mMapSpan.Append(goMMap)
|
||||
}
|
||||
log.Println(len(metaInfo.Info.Files))
|
||||
log.Println(mMapSpan.Size())
|
||||
|
|
5
misc.go
5
misc.go
|
@ -125,7 +125,8 @@ func upvertedSingleFileInfoFiles(info *metainfo.Info) []metainfo.FileInfo {
|
|||
return []metainfo.FileInfo{{Length: info.Length, Path: nil}}
|
||||
}
|
||||
|
||||
func mmapTorrentData(md *metainfo.Info, location string) (mms mmap_span.MMapSpan, err error) {
|
||||
func mmapTorrentData(md *metainfo.Info, location string) (mms *mmap_span.MMapSpan, err error) {
|
||||
mms = &mmap_span.MMapSpan{}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
mms.Close()
|
||||
|
@ -170,7 +171,7 @@ func mmapTorrentData(md *metainfo.Info, location string) (mms mmap_span.MMapSpan
|
|||
if int64(len(mMap)) != miFile.Length {
|
||||
panic("mmap has wrong length")
|
||||
}
|
||||
mms = append(mms, mMap)
|
||||
mms.Append(mMap)
|
||||
}()
|
||||
if err != nil {
|
||||
return
|
||||
|
|
|
@ -14,30 +14,29 @@ func (me segment) Size() int64 {
|
|||
return int64(len(me.MMap))
|
||||
}
|
||||
|
||||
type MMapSpan []gommap.MMap
|
||||
|
||||
func (me MMapSpan) span() (s span) {
|
||||
for _, mmap := range me {
|
||||
s = append(s, segment{mmap})
|
||||
type MMapSpan struct {
|
||||
span
|
||||
}
|
||||
return
|
||||
|
||||
func (me *MMapSpan) Append(mmap gommap.MMap) {
|
||||
me.span = append(me.span, segment{mmap})
|
||||
}
|
||||
|
||||
func (me MMapSpan) Close() {
|
||||
for _, mMap := range me {
|
||||
mMap.UnsafeUnmap()
|
||||
for _, mMap := range me.span {
|
||||
mMap.(segment).UnsafeUnmap()
|
||||
}
|
||||
}
|
||||
|
||||
func (me MMapSpan) Size() (ret int64) {
|
||||
for _, seg := range me.span() {
|
||||
for _, seg := range me.span {
|
||||
ret += seg.Size()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (me MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
me.span().ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
|
||||
me.ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
|
||||
_n := copy(p, interval.(segment).MMap[intervalOffset:])
|
||||
p = p[_n:]
|
||||
n += _n
|
||||
|
@ -50,7 +49,7 @@ func (me MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
|
|||
}
|
||||
|
||||
func (me MMapSpan) WriteSectionTo(w io.Writer, off, n int64) (written int64, err error) {
|
||||
me.span().ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
|
||||
me.ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
|
||||
var _n int
|
||||
p := interval.(segment).MMap[intervalOffset:]
|
||||
if n < int64(len(p)) {
|
||||
|
@ -68,7 +67,7 @@ func (me MMapSpan) WriteSectionTo(w io.Writer, off, n int64) (written int64, err
|
|||
}
|
||||
|
||||
func (me MMapSpan) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
me.span().ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
|
||||
me.ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
|
||||
mMap := i.(segment)
|
||||
_n := copy(mMap.MMap[iOff:], p)
|
||||
// err = mMap.Sync(gommap.MS_ASYNC)
|
||||
|
|
|
@ -60,7 +60,7 @@ type torrent struct {
|
|||
length int64
|
||||
// Prevent mutations to Data memory maps while in use as they're not safe.
|
||||
dataLock sync.RWMutex
|
||||
Data mmap_span.MMapSpan
|
||||
Data *mmap_span.MMapSpan
|
||||
|
||||
Info *MetaInfo
|
||||
// Active peer connections.
|
||||
|
@ -459,8 +459,10 @@ func (t *torrent) Close() (err error) {
|
|||
t.CeaseNetworking()
|
||||
close(t.closing)
|
||||
t.dataLock.Lock()
|
||||
if t.Data != nil {
|
||||
t.Data.Close()
|
||||
t.Data = nil
|
||||
}
|
||||
t.dataLock.Unlock()
|
||||
for _, conn := range t.Conns {
|
||||
conn.Close()
|
||||
|
|
Loading…
Reference in New Issue