]> Sergey Matveev's repositories - btrtrc.git/blob - mmap_span/mmap_span.go
Merge remote-tracking branch 'libtorgo/master' into HEAD
[btrtrc.git] / mmap_span / mmap_span.go
1 package mmap_span
2
3 import (
4         "io"
5
6         "launchpad.net/gommap"
7 )
8
9 type segment struct {
10         gommap.MMap
11 }
12
13 func (me segment) Size() int64 {
14         return int64(len(me.MMap))
15 }
16
17 type MMapSpan struct {
18         span
19 }
20
21 func (me *MMapSpan) Append(mmap gommap.MMap) {
22         me.span = append(me.span, segment{mmap})
23 }
24
25 func (me MMapSpan) Close() {
26         for _, mMap := range me.span {
27                 mMap.(segment).UnsafeUnmap()
28         }
29 }
30
31 func (me MMapSpan) Size() (ret int64) {
32         for _, seg := range me.span {
33                 ret += seg.Size()
34         }
35         return
36 }
37
38 func (me MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
39         me.ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
40                 _n := copy(p, interval.(segment).MMap[intervalOffset:])
41                 p = p[_n:]
42                 n += _n
43                 return len(p) == 0
44         })
45         if len(p) != 0 {
46                 err = io.EOF
47         }
48         return
49 }
50
51 func (me MMapSpan) WriteSectionTo(w io.Writer, off, n int64) (written int64, err error) {
52         me.ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
53                 var _n int
54                 p := interval.(segment).MMap[intervalOffset:]
55                 if n < int64(len(p)) {
56                         p = p[:n]
57                 }
58                 _n, err = w.Write(p)
59                 written += int64(_n)
60                 n -= int64(_n)
61                 if err != nil {
62                         return true
63                 }
64                 return n == 0
65         })
66         return
67 }
68
69 func (me MMapSpan) WriteAt(p []byte, off int64) (n int, err error) {
70         me.ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
71                 mMap := i.(segment)
72                 _n := copy(mMap.MMap[iOff:], p)
73                 // err = mMap.Sync(gommap.MS_ASYNC)
74                 // if err != nil {
75                 //      return true
76                 // }
77                 p = p[_n:]
78                 n += _n
79                 return len(p) == 0
80         })
81         if err != nil && len(p) != 0 {
82                 err = io.ErrShortWrite
83         }
84         return
85 }