From: Matt Joiner Date: Thu, 26 Sep 2013 03:42:24 +0000 (+1000) Subject: Add torrent.Mmap and MmapSpan, types that abstract memory-mapped torrent data X-Git-Tag: v1.0.0~1824 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=3d1fb69e368bb5191ca64b56601b0e24889f4c2c;p=btrtrc.git Add torrent.Mmap and MmapSpan, types that abstract memory-mapped torrent data --- diff --git a/mmap_span.go b/mmap_span.go new file mode 100644 index 00000000..e8514168 --- /dev/null +++ b/mmap_span.go @@ -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 +} diff --git a/span.go b/span.go new file mode 100644 index 00000000..b744926b --- /dev/null +++ b/span.go @@ -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 + } + } +}