8 "github.com/anacrolix/torrent/segments"
17 type MMapSpan struct {
20 segmentLocater segments.Index
23 func (ms *MMapSpan) Append(mMap Mmap) {
24 ms.mMaps = append(ms.mMaps, mMap)
27 func (ms *MMapSpan) Flush() (errs []error) {
30 for _, mMap := range ms.mMaps {
33 errs = append(errs, err)
39 func (ms *MMapSpan) Close() (errs []error) {
42 for _, mMap := range ms.mMaps {
45 errs = append(errs, err)
48 // This is for issue 211.
54 func (me *MMapSpan) InitIndex() {
56 me.segmentLocater = segments.NewIndex(func() (segments.Length, bool) {
57 if i == len(me.mMaps) {
60 l := int64(len(me.mMaps[i].Bytes()))
64 // log.Printf("made mmapspan index: %v", me.segmentLocater)
67 func (ms *MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
68 // log.Printf("reading %v bytes at %v", len(p), off)
71 n = ms.locateCopy(func(a, b []byte) (_, _ []byte) { return a, b }, p, off)
78 func copyBytes(dst, src []byte) int {
82 func (ms *MMapSpan) locateCopy(copyArgs func(remainingArgument, mmapped []byte) (dst, src []byte), p []byte, off int64) (n int) {
83 ms.segmentLocater.Locate(segments.Extent{off, int64(len(p))}, func(i int, e segments.Extent) bool {
84 mMapBytes := ms.mMaps[i].Bytes()[e.Start:]
85 // log.Printf("got segment %v: %v, copying %v, %v", i, e, len(p), len(mMapBytes))
86 _n := copyBytes(copyArgs(p, mMapBytes))
90 if segments.Int(_n) != e.Length {
91 panic(fmt.Sprintf("did %d bytes, expected to do %d", _n, e.Length))
98 func (ms *MMapSpan) WriteAt(p []byte, off int64) (n int, err error) {
99 // log.Printf("writing %v bytes at %v", len(p), off)
101 defer ms.mu.RUnlock()
102 n = ms.locateCopy(func(a, b []byte) (_, _ []byte) { return b, a }, p, off)
104 err = io.ErrShortWrite