Add torrent.Mmap and MmapSpan, types that abstract memory-mapped torrent data

This commit is contained in:
Matt Joiner 2013-09-26 13:42:24 +10:00
parent 2a9d48d09f
commit 3d1fb69e36
2 changed files with 79 additions and 0 deletions

56
mmap_span.go Normal file
View File

@ -0,0 +1,56 @@
package torrent
import (
"io"
"launchpad.net/gommap"
)
type Mmap struct {
gommap.MMap
}
func (me Mmap) Size() int64 {
return int64(len(me.MMap))
}
type MmapSpan []Mmap
func (me MmapSpan) span() (s span) {
for _, mmap := range me {
s = append(s, mmap)
}
return
}
func (me MmapSpan) Size() (ret int64) {
for _, mmap := range me {
ret += mmap.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) {
_n := copy(p, interval.(Mmap).MMap[intervalOffset:])
p = p[_n:]
n += _n
return len(p) == 0
})
if len(p) != 0 {
err = io.EOF
}
return
}
func (me MmapSpan) WriteAt(p []byte, off int64) (n int, err error) {
me.span().ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
_n := copy(i.(Mmap).MMap[iOff:], p)
p = p[_n:]
n += _n
return len(p) == 0
})
if len(p) != 0 {
err = io.EOF
}
return
}

23
span.go Normal file
View File

@ -0,0 +1,23 @@
package torrent
type sizer interface {
Size() int64
}
type (
span []sizer
)
func (me span) ApplyTo(off int64, f func(int64, sizer) (stop bool)) {
for _, interval := range me {
iSize := interval.Size()
if off >= iSize {
off -= iSize
} else {
if f(off, interval) {
return
}
off = 0
}
}
}