]> Sergey Matveev's repositories - btrtrc.git/commitdiff
data/blob: Change store eviction to LRU, from random replacement
authorMatt Joiner <anacrolix@gmail.com>
Wed, 18 Mar 2015 07:12:46 +0000 (18:12 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 18 Mar 2015 07:12:46 +0000 (18:12 +1100)
It works *much* better for torrenting with a readahead window. When we want to
avoid downloading, we want to avoid downloading lots of dispersed pieces.

data/blob/atime_darwin.go [new file with mode: 0644]
data/blob/atime_linux.go [new file with mode: 0644]
data/blob/store.go

diff --git a/data/blob/atime_darwin.go b/data/blob/atime_darwin.go
new file mode 100644 (file)
index 0000000..33091d5
--- /dev/null
@@ -0,0 +1,12 @@
+package blob
+
+import (
+       "os"
+       "syscall"
+       "time"
+)
+
+func accessTime(fi os.FileInfo) time.Time {
+       ts := fi.Sys().(*syscall.Stat_t).Atimespec
+       return time.Unix(ts.Sec, ts.Nano())
+}
diff --git a/data/blob/atime_linux.go b/data/blob/atime_linux.go
new file mode 100644 (file)
index 0000000..3bcc054
--- /dev/null
@@ -0,0 +1,12 @@
+package blob
+
+import (
+       "os"
+       "syscall"
+       "time"
+)
+
+func accessTime(fi os.FileInfo) time.Time {
+       ts := fi.Sys().(*syscall.Stat_t).Atim
+       return time.Unix(ts.Sec, ts.Nano())
+}
index 766129f35b8bc6412bb394761a8c037d97310b41..cb8f2aa81784d03564e7c48e63d926803b80e0c6 100644 (file)
@@ -10,6 +10,8 @@ import (
        "math/rand"
        "os"
        "path/filepath"
+       "sort"
+       "time"
 
        dataPkg "bitbucket.org/anacrolix/go.torrent/data"
        "github.com/anacrolix/libtorgo/metainfo"
@@ -133,6 +135,36 @@ func (me *store) removeCompleted(name string) (err error) {
        return
 }
 
+type fileInfoSorter struct {
+       fis []os.FileInfo
+}
+
+func (me fileInfoSorter) Len() int {
+       return len(me.fis)
+}
+
+func lastTime(fi os.FileInfo) (ret time.Time) {
+       ret = fi.ModTime()
+       atime := accessTime(fi)
+       if atime.After(ret) {
+               ret = atime
+       }
+       return
+}
+
+func (me fileInfoSorter) Less(i, j int) bool {
+       return lastTime(me.fis[i]).Before(lastTime(me.fis[j]))
+}
+
+func (me fileInfoSorter) Swap(i, j int) {
+       me.fis[i], me.fis[j] = me.fis[j], me.fis[i]
+}
+
+func sortFileInfos(fis []os.FileInfo) {
+       sorter := fileInfoSorter{fis}
+       sort.Sort(sorter)
+}
+
 func (me *store) makeSpace(space int64) error {
        if me.capacity < 0 {
                return nil
@@ -148,12 +180,11 @@ func (me *store) makeSpace(space int64) error {
        for _, fi := range fis {
                size += fi.Size()
        }
+       sortFileInfos(fis)
        for size > me.capacity-space {
-               i := rand.Intn(len(fis))
-               me.removeCompleted(fis[i].Name())
-               size -= fis[i].Size()
-               fis[i] = fis[len(fis)-1]
-               fis = fis[:len(fis)-1]
+               me.removeCompleted(fis[0].Name())
+               size -= fis[0].Size()
+               fis = fis[1:]
        }
        return nil
 }