You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
1.8 KiB

5 years ago
  1. package backend
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/glog"
  4. "github.com/chrislusf/seaweedfs/weed/util/buffered_writer"
  5. "os"
  6. "time"
  7. )
  8. var (
  9. _ BackendStorageFile = &DiskFile{}
  10. )
  11. type DiskFile struct {
  12. File *os.File
  13. fullFilePath string
  14. bufWriterAt *buffered_writer.TimedWriteBuffer
  15. fileSize int64
  16. modTime time.Time
  17. }
  18. func NewDiskFile(f *os.File) *DiskFile {
  19. stat, e := f.Stat()
  20. if e != nil {
  21. glog.Fatalf("stat file %s: %v", f.Name(), e)
  22. }
  23. return &DiskFile{
  24. fullFilePath: f.Name(),
  25. File: f,
  26. bufWriterAt: buffered_writer.NewTimedWriteBuffer(f, 1*1024*1024, 200*time.Millisecond, stat.Size()),
  27. fileSize: stat.Size(),
  28. modTime: stat.ModTime(),
  29. }
  30. }
  31. func (df *DiskFile) ReadAt(p []byte, off int64) (n int, err error) {
  32. n, _ = df.bufWriterAt.ReadAt(p, off)
  33. if len(p) == n {
  34. return
  35. }
  36. return df.File.ReadAt(p, off)
  37. }
  38. func (df *DiskFile) WriteAt(p []byte, off int64) (n int, err error) {
  39. n, err = df.bufWriterAt.WriteAt(p, off)
  40. if err == nil {
  41. waterMark := off + int64(n)
  42. if waterMark > df.fileSize {
  43. df.fileSize = waterMark
  44. df.modTime = time.Now()
  45. }
  46. }
  47. return
  48. }
  49. func (df *DiskFile) Truncate(off int64) error {
  50. err := df.File.Truncate(off)
  51. if err == nil {
  52. df.fileSize = off
  53. df.modTime = time.Now()
  54. }
  55. return err
  56. }
  57. func (df *DiskFile) Close() error {
  58. df.bufWriterAt.Close()
  59. return df.File.Close()
  60. }
  61. func (df *DiskFile) GetStat() (datSize int64, modTime time.Time, err error) {
  62. if df.fileSize != 0 {
  63. return df.fileSize, df.modTime, nil
  64. }
  65. stat, e := df.File.Stat()
  66. if e == nil {
  67. return stat.Size(), stat.ModTime(), nil
  68. }
  69. return 0, time.Time{}, err
  70. }
  71. func (df *DiskFile) Name() string {
  72. return df.fullFilePath
  73. }
  74. func (df *DiskFile) Sync() error {
  75. df.fileSize = 0
  76. df.bufWriterAt.Flush()
  77. return df.File.Sync()
  78. }