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.

181 lines
4.9 KiB

4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
3 years ago
4 years ago
  1. package filer_pb
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "os"
  7. "strings"
  8. "time"
  9. "github.com/seaweedfs/seaweedfs/weed/glog"
  10. "github.com/seaweedfs/seaweedfs/weed/storage/needle"
  11. "github.com/viant/ptrie"
  12. "google.golang.org/protobuf/proto"
  13. )
  14. const cutoffTimeNewEmptyDir = 3
  15. func (entry *Entry) IsInRemoteOnly() bool {
  16. return len(entry.GetChunks()) == 0 && entry.RemoteEntry != nil && entry.RemoteEntry.RemoteSize > 0
  17. }
  18. func (entry *Entry) IsDirectoryKeyObject() bool {
  19. return entry.IsDirectory && entry.Attributes != nil && entry.Attributes.Mime != ""
  20. }
  21. func (entry *Entry) FileMode() (fileMode os.FileMode) {
  22. if entry != nil && entry.Attributes != nil {
  23. fileMode = os.FileMode(entry.Attributes.FileMode)
  24. }
  25. return
  26. }
  27. func (entry *Entry) IsOlderDir() bool {
  28. return entry.IsDirectory && entry.Attributes != nil && entry.Attributes.Mime == "" && entry.Attributes.GetCrtime() <= time.Now().Unix()-cutoffTimeNewEmptyDir
  29. }
  30. func ToFileIdObject(fileIdStr string) (*FileId, error) {
  31. t, err := needle.ParseFileIdFromString(fileIdStr)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return &FileId{
  36. VolumeId: uint32(t.VolumeId),
  37. Cookie: uint32(t.Cookie),
  38. FileKey: uint64(t.Key),
  39. }, nil
  40. }
  41. func (fid *FileId) toFileIdString() string {
  42. return needle.NewFileId(needle.VolumeId(fid.VolumeId), fid.FileKey, fid.Cookie).String()
  43. }
  44. func (c *FileChunk) GetFileIdString() string {
  45. if c.FileId != "" {
  46. return c.FileId
  47. }
  48. if c.Fid != nil {
  49. c.FileId = c.Fid.toFileIdString()
  50. return c.FileId
  51. }
  52. return ""
  53. }
  54. func BeforeEntrySerialization(chunks []*FileChunk) {
  55. for _, chunk := range chunks {
  56. if chunk.FileId != "" {
  57. if fid, err := ToFileIdObject(chunk.FileId); err == nil {
  58. chunk.Fid = fid
  59. chunk.FileId = ""
  60. }
  61. }
  62. if chunk.SourceFileId != "" {
  63. if fid, err := ToFileIdObject(chunk.SourceFileId); err == nil {
  64. chunk.SourceFid = fid
  65. chunk.SourceFileId = ""
  66. }
  67. }
  68. }
  69. }
  70. func EnsureFid(chunk *FileChunk) {
  71. if chunk.Fid != nil {
  72. return
  73. }
  74. if fid, err := ToFileIdObject(chunk.FileId); err == nil {
  75. chunk.Fid = fid
  76. }
  77. }
  78. func AfterEntryDeserialization(chunks []*FileChunk) {
  79. for _, chunk := range chunks {
  80. if chunk.Fid != nil && chunk.FileId == "" {
  81. chunk.FileId = chunk.Fid.toFileIdString()
  82. }
  83. if chunk.SourceFid != nil && chunk.SourceFileId == "" {
  84. chunk.SourceFileId = chunk.SourceFid.toFileIdString()
  85. }
  86. }
  87. }
  88. func CreateEntry(client SeaweedFilerClient, request *CreateEntryRequest) error {
  89. resp, err := client.CreateEntry(context.Background(), request)
  90. if err != nil {
  91. glog.V(1).Infof("create entry %s/%s %v: %v", request.Directory, request.Entry.Name, request.OExcl, err)
  92. return fmt.Errorf("CreateEntry: %v", err)
  93. }
  94. if resp.Error != "" {
  95. glog.V(1).Infof("create entry %s/%s %v: %v", request.Directory, request.Entry.Name, request.OExcl, resp.Error)
  96. return fmt.Errorf("CreateEntry : %v", resp.Error)
  97. }
  98. return nil
  99. }
  100. func UpdateEntry(client SeaweedFilerClient, request *UpdateEntryRequest) error {
  101. _, err := client.UpdateEntry(context.Background(), request)
  102. if err != nil {
  103. glog.V(1).Infof("update entry %s/%s :%v", request.Directory, request.Entry.Name, err)
  104. return fmt.Errorf("UpdateEntry: %v", err)
  105. }
  106. return nil
  107. }
  108. func LookupEntry(client SeaweedFilerClient, request *LookupDirectoryEntryRequest) (*LookupDirectoryEntryResponse, error) {
  109. resp, err := client.LookupDirectoryEntry(context.Background(), request)
  110. if err != nil {
  111. if err == ErrNotFound || strings.Contains(err.Error(), ErrNotFound.Error()) {
  112. return nil, ErrNotFound
  113. }
  114. glog.V(3).Infof("read %s/%v: %v", request.Directory, request.Name, err)
  115. return nil, fmt.Errorf("LookupEntry1: %v", err)
  116. }
  117. if resp.Entry == nil {
  118. return nil, ErrNotFound
  119. }
  120. return resp, nil
  121. }
  122. var ErrNotFound = errors.New("filer: no entry is found in filer store")
  123. func IsEmpty(event *SubscribeMetadataResponse) bool {
  124. return event.EventNotification.NewEntry == nil && event.EventNotification.OldEntry == nil
  125. }
  126. func IsCreate(event *SubscribeMetadataResponse) bool {
  127. return event.EventNotification.NewEntry != nil && event.EventNotification.OldEntry == nil
  128. }
  129. func IsUpdate(event *SubscribeMetadataResponse) bool {
  130. return event.EventNotification.NewEntry != nil &&
  131. event.EventNotification.OldEntry != nil &&
  132. event.Directory == event.EventNotification.NewParentPath &&
  133. event.EventNotification.NewEntry.Name == event.EventNotification.OldEntry.Name
  134. }
  135. func IsDelete(event *SubscribeMetadataResponse) bool {
  136. return event.EventNotification.NewEntry == nil && event.EventNotification.OldEntry != nil
  137. }
  138. func IsRename(event *SubscribeMetadataResponse) bool {
  139. return event.EventNotification.NewEntry != nil &&
  140. event.EventNotification.OldEntry != nil &&
  141. (event.Directory != event.EventNotification.NewParentPath ||
  142. event.EventNotification.NewEntry.Name != event.EventNotification.OldEntry.Name)
  143. }
  144. var _ = ptrie.KeyProvider(&FilerConf_PathConf{})
  145. func (fp *FilerConf_PathConf) Key() interface{} {
  146. key, _ := proto.Marshal(fp)
  147. return string(key)
  148. }