file-piece.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package storage
  2. import (
  3. "io"
  4. "log"
  5. "os"
  6. "github.com/anacrolix/torrent/metainfo"
  7. "github.com/anacrolix/torrent/segments"
  8. )
  9. type filePieceImpl struct {
  10. *fileTorrentImpl
  11. p metainfo.Piece
  12. io.WriterAt
  13. io.ReaderAt
  14. }
  15. var _ PieceImpl = (*filePieceImpl)(nil)
  16. func (me *filePieceImpl) pieceKey() metainfo.PieceKey {
  17. return metainfo.PieceKey{me.infoHash, me.p.Index()}
  18. }
  19. func (fs *filePieceImpl) Completion() Completion {
  20. c, err := fs.completion.Get(fs.pieceKey())
  21. if err != nil {
  22. log.Printf("error getting piece completion: %s", err)
  23. c.Ok = false
  24. return c
  25. }
  26. verified := true
  27. if c.Complete {
  28. // If it's allegedly complete, check that its constituent files have the necessary length.
  29. if !fs.segmentLocater.Locate(segments.Extent{
  30. Start: fs.p.Offset(),
  31. Length: fs.p.Length(),
  32. }, func(i int, extent segments.Extent) bool {
  33. file := fs.files[i]
  34. s, err := os.Stat(file.path)
  35. if err != nil || s.Size() < extent.Start+extent.Length {
  36. verified = false
  37. return false
  38. }
  39. return true
  40. }) {
  41. panic("files do not cover piece extent")
  42. }
  43. }
  44. if !verified {
  45. // The completion was wrong, fix it.
  46. c.Complete = false
  47. fs.completion.Set(fs.pieceKey(), false)
  48. }
  49. return c
  50. }
  51. func (fs *filePieceImpl) MarkComplete() error {
  52. return fs.completion.Set(fs.pieceKey(), true)
  53. }
  54. func (fs *filePieceImpl) MarkNotComplete() error {
  55. return fs.completion.Set(fs.pieceKey(), false)
  56. }