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.

111 lines
2.4 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package mount
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/filer"
  4. "github.com/chrislusf/seaweedfs/weed/glog"
  5. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  6. "github.com/chrislusf/seaweedfs/weed/util"
  7. "golang.org/x/exp/slices"
  8. "io"
  9. "sync"
  10. )
  11. type FileHandleId uint64
  12. type FileHandle struct {
  13. fh FileHandleId
  14. counter int64
  15. entry *filer_pb.Entry
  16. entryLock sync.Mutex
  17. inode uint64
  18. wfs *WFS
  19. // cache file has been written to
  20. dirtyMetadata bool
  21. dirtyPages *PageWriter
  22. entryViewCache []filer.VisibleInterval
  23. reader io.ReaderAt
  24. contentType string
  25. handle uint64
  26. sync.Mutex
  27. isDeleted bool
  28. }
  29. func newFileHandle(wfs *WFS, handleId FileHandleId, inode uint64, entry *filer_pb.Entry) *FileHandle {
  30. fh := &FileHandle{
  31. fh: handleId,
  32. counter: 1,
  33. inode: inode,
  34. wfs: wfs,
  35. }
  36. // dirtyPages: newContinuousDirtyPages(file, writeOnly),
  37. fh.dirtyPages = newPageWriter(fh, wfs.option.ChunkSizeLimit)
  38. if entry != nil {
  39. entry.Attributes.FileSize = filer.FileSize(entry)
  40. }
  41. return fh
  42. }
  43. func (fh *FileHandle) FullPath() util.FullPath {
  44. fp, _ := fh.wfs.inodeToPath.GetPath(fh.inode)
  45. return fp
  46. }
  47. func (fh *FileHandle) GetEntry() *filer_pb.Entry {
  48. fh.entryLock.Lock()
  49. defer fh.entryLock.Unlock()
  50. return fh.entry
  51. }
  52. func (fh *FileHandle) SetEntry(entry *filer_pb.Entry) {
  53. fh.entryLock.Lock()
  54. defer fh.entryLock.Unlock()
  55. fh.entry = entry
  56. }
  57. func (fh *FileHandle) AddChunks(chunks []*filer_pb.FileChunk) {
  58. fh.entryLock.Lock()
  59. defer fh.entryLock.Unlock()
  60. // find the earliest incoming chunk
  61. newChunks := chunks
  62. earliestChunk := newChunks[0]
  63. for i := 1; i < len(newChunks); i++ {
  64. if lessThan(earliestChunk, newChunks[i]) {
  65. earliestChunk = newChunks[i]
  66. }
  67. }
  68. if fh.entry == nil {
  69. return
  70. }
  71. // pick out-of-order chunks from existing chunks
  72. for _, chunk := range fh.entry.Chunks {
  73. if lessThan(earliestChunk, chunk) {
  74. chunks = append(chunks, chunk)
  75. }
  76. }
  77. // sort incoming chunks
  78. slices.SortFunc(chunks, func(a, b *filer_pb.FileChunk) bool {
  79. return lessThan(a, b)
  80. })
  81. glog.V(4).Infof("%s existing %d chunks adds %d more", fh.FullPath(), len(fh.entry.Chunks), len(chunks))
  82. fh.entry.Chunks = append(fh.entry.Chunks, newChunks...)
  83. fh.entryViewCache = nil
  84. }
  85. func (fh *FileHandle) Release() {
  86. fh.dirtyPages.Destroy()
  87. }
  88. func lessThan(a, b *filer_pb.FileChunk) bool {
  89. if a.Mtime == b.Mtime {
  90. return a.Fid.FileKey < b.Fid.FileKey
  91. }
  92. return a.Mtime < b.Mtime
  93. }