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.

112 lines
2.6 KiB

10 years ago
10 years ago
  1. package operation
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net/url"
  6. "strings"
  7. "sync"
  8. "net/http"
  9. "github.com/chrislusf/seaweedfs/go/security"
  10. "github.com/chrislusf/seaweedfs/go/util"
  11. )
  12. type DeleteResult struct {
  13. Fid string `json:"fid"`
  14. Size int `json:"size"`
  15. Status int `json:"status"`
  16. Error string `json:"error,omitempty"`
  17. }
  18. func DeleteFile(master string, fileId string, jwt security.EncodedJwt) error {
  19. fileUrl, err := LookupFileId(master, fileId)
  20. if err != nil {
  21. return err
  22. }
  23. return util.Delete(fileUrl, jwt)
  24. }
  25. func ParseFileId(fid string) (vid string, key_cookie string, err error) {
  26. commaIndex := strings.Index(fid, ",")
  27. if commaIndex <= 0 {
  28. return "", "", errors.New("Wrong fid format.")
  29. }
  30. return fid[:commaIndex], fid[commaIndex+1:], nil
  31. }
  32. type DeleteFilesResult struct {
  33. Errors []string
  34. Results []DeleteResult
  35. }
  36. func DeleteFiles(master string, fileIds []string) (*DeleteFilesResult, error) {
  37. vid_to_fileIds := make(map[string][]string)
  38. ret := &DeleteFilesResult{}
  39. var vids []string
  40. for _, fileId := range fileIds {
  41. vid, _, err := ParseFileId(fileId)
  42. if err != nil {
  43. ret.Results = append(ret.Results, DeleteResult{
  44. Fid: vid,
  45. Status: http.StatusBadRequest,
  46. Error: err.Error()},
  47. )
  48. continue
  49. }
  50. if _, ok := vid_to_fileIds[vid]; !ok {
  51. vid_to_fileIds[vid] = make([]string, 0)
  52. vids = append(vids, vid)
  53. }
  54. vid_to_fileIds[vid] = append(vid_to_fileIds[vid], fileId)
  55. }
  56. lookupResults, err := LookupVolumeIds(master, vids)
  57. if err != nil {
  58. return ret, err
  59. }
  60. server_to_fileIds := make(map[string][]string)
  61. for vid, result := range lookupResults {
  62. if result.Error != "" {
  63. ret.Errors = append(ret.Errors, result.Error)
  64. continue
  65. }
  66. for _, location := range result.Locations {
  67. if _, ok := server_to_fileIds[location.Url]; !ok {
  68. server_to_fileIds[location.Url] = make([]string, 0)
  69. }
  70. server_to_fileIds[location.Url] = append(
  71. server_to_fileIds[location.Url], vid_to_fileIds[vid]...)
  72. }
  73. }
  74. var wg sync.WaitGroup
  75. for server, fidList := range server_to_fileIds {
  76. wg.Add(1)
  77. go func(server string, fidList []string) {
  78. defer wg.Done()
  79. values := make(url.Values)
  80. for _, fid := range fidList {
  81. values.Add("fid", fid)
  82. }
  83. jsonBlob, err := util.Post("http://"+server+"/delete", values)
  84. if err != nil {
  85. ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
  86. return
  87. }
  88. var result []DeleteResult
  89. err = json.Unmarshal(jsonBlob, &result)
  90. if err != nil {
  91. ret.Errors = append(ret.Errors, err.Error()+" "+string(jsonBlob))
  92. return
  93. }
  94. ret.Results = append(ret.Results, result...)
  95. }(server, fidList)
  96. }
  97. wg.Wait()
  98. return ret, nil
  99. }