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.

94 lines
2.1 KiB

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. "io"
  8. "sort"
  9. "sync"
  10. )
  11. type FileHandleId uint64
  12. type FileHandle struct {
  13. fh FileHandleId
  14. counter int64
  15. entry *filer_pb.Entry
  16. chunkAddLock sync.Mutex
  17. inode uint64
  18. wfs *WFS
  19. // cache file has been written to
  20. dirtyPages *PageWriter
  21. entryViewCache []filer.VisibleInterval
  22. reader io.ReaderAt
  23. contentType string
  24. handle uint64
  25. sync.Mutex
  26. isDeleted bool
  27. }
  28. func newFileHandle(wfs *WFS, handleId FileHandleId, inode uint64, entry *filer_pb.Entry) *FileHandle {
  29. fh := &FileHandle{
  30. fh: handleId,
  31. counter: 1,
  32. inode: inode,
  33. wfs: wfs,
  34. }
  35. // dirtyPages: newContinuousDirtyPages(file, writeOnly),
  36. fh.dirtyPages = newPageWriter(fh, wfs.option.ChunkSizeLimit)
  37. if entry != nil {
  38. entry.Attributes.FileSize = filer.FileSize(entry)
  39. }
  40. return fh
  41. }
  42. func (fh *FileHandle) FullPath() util.FullPath {
  43. return fh.wfs.inodeToPath.GetPath(fh.inode)
  44. }
  45. func (fh *FileHandle) addChunks(chunks []*filer_pb.FileChunk) {
  46. // find the earliest incoming chunk
  47. newChunks := chunks
  48. earliestChunk := newChunks[0]
  49. for i := 1; i < len(newChunks); i++ {
  50. if lessThan(earliestChunk, newChunks[i]) {
  51. earliestChunk = newChunks[i]
  52. }
  53. }
  54. if fh.entry == nil {
  55. return
  56. }
  57. // pick out-of-order chunks from existing chunks
  58. for _, chunk := range fh.entry.Chunks {
  59. if lessThan(earliestChunk, chunk) {
  60. chunks = append(chunks, chunk)
  61. }
  62. }
  63. // sort incoming chunks
  64. sort.Slice(chunks, func(i, j int) bool {
  65. return lessThan(chunks[i], chunks[j])
  66. })
  67. glog.V(4).Infof("%s existing %d chunks adds %d more", fh.FullPath(), len(fh.entry.Chunks), len(chunks))
  68. fh.chunkAddLock.Lock()
  69. fh.entry.Chunks = append(fh.entry.Chunks, newChunks...)
  70. fh.entryViewCache = nil
  71. fh.chunkAddLock.Unlock()
  72. }
  73. func lessThan(a, b *filer_pb.FileChunk) bool {
  74. if a.Mtime == b.Mtime {
  75. return a.Fid.FileKey < b.Fid.FileKey
  76. }
  77. return a.Mtime < b.Mtime
  78. }