package main import ( "os" "sync" "github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/storage" ) type BFPieceCompletion struct { sync.Mutex } func NewBFPieceCompletion() *BFPieceCompletion { return &BFPieceCompletion{} } func (self *BFPieceCompletion) Get(pk metainfo.PieceKey) (c storage.Completion, rerr error) { self.Lock() defer self.Unlock() fd, err := os.OpenFile(pk.InfoHash.HexString()+".bf", os.O_RDWR|os.O_CREATE, 0666) if err != nil { rerr = err return } defer fd.Close() b := []byte{0} _, err = fd.ReadAt(b, int64(pk.Index)) if err != nil { return } c.Ok = true switch string(b) { case "0": c.Complete = false case "1": c.Complete = true default: c.Ok = false } return } func (self *BFPieceCompletion) Set(pk metainfo.PieceKey, complete bool) error { if c, err := self.Get(pk); err == nil && c.Ok && c.Complete == complete { return nil } self.Lock() defer self.Unlock() fd, err := os.OpenFile(pk.InfoHash.HexString()+".bf", os.O_RDWR|os.O_CREATE, 0666) if err != nil { return err } defer fd.Close() b := []byte{'1'} if !complete { b[0] = '0' } if _, err = fd.WriteAt(b, int64(pk.Index)); err != nil { return err } return nil } func (self *BFPieceCompletion) Close() error { return nil }