]> Sergey Matveev's repositories - btrtrc.git/blob - mmap_span/mmap_span.go
Ditch Data.WriteSectionTo, and fix cmd/torrent-verify
[btrtrc.git] / mmap_span / mmap_span.go
1 package mmap_span
2
3 import (
4         "io"
5
6         "github.com/edsrzf/mmap-go"
7 )
8
9 type segment struct {
10         *mmap.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 mmap.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).Unmap()
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) WriteAt(p []byte, off int64) (n int, err error) {
52         me.ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
53                 mMap := i.(segment)
54                 _n := copy((*mMap.MMap)[iOff:], p)
55                 // err = mMap.Sync(gommap.MS_ASYNC)
56                 // if err != nil {
57                 //      return true
58                 // }
59                 p = p[_n:]
60                 n += _n
61                 return len(p) == 0
62         })
63         if err != nil && len(p) != 0 {
64                 err = io.ErrShortWrite
65         }
66         return
67 }