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.

120 lines
2.5 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package wdclient
  2. import (
  3. "errors"
  4. "fmt"
  5. "math/rand"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "github.com/chrislusf/seaweedfs/weed/glog"
  10. )
  11. type Location struct {
  12. Url string `json:"url,omitempty"`
  13. PublicUrl string `json:"publicUrl,omitempty"`
  14. }
  15. type vidMap struct {
  16. sync.RWMutex
  17. vid2Locations map[uint32][]Location
  18. }
  19. func newVidMap() vidMap {
  20. return vidMap{
  21. vid2Locations: make(map[uint32][]Location),
  22. }
  23. }
  24. func (vc *vidMap) LookupVolumeServerUrl(vid string) (serverUrl string, err error) {
  25. id, err := strconv.Atoi(vid)
  26. if err != nil {
  27. glog.V(1).Infof("Unknown volume id %s", vid)
  28. return "", err
  29. }
  30. locations := vc.GetLocations(uint32(id))
  31. if len(locations) == 0 {
  32. return "", fmt.Errorf("volume %d not found", id)
  33. }
  34. return locations[rand.Intn(len(locations))].Url, nil
  35. }
  36. func (vc *vidMap) LookupFileId(fileId string) (fullUrl string, err error) {
  37. parts := strings.Split(fileId, ",")
  38. if len(parts) != 2 {
  39. return "", errors.New("Invalid fileId " + fileId)
  40. }
  41. serverUrl, lookupError := vc.LookupVolumeServerUrl(parts[0])
  42. if lookupError != nil {
  43. return "", lookupError
  44. }
  45. return "http://" + serverUrl + "/" + fileId, nil
  46. }
  47. func (vc *vidMap) LookupVolumeServer(fileId string) (volumeServer string, err error) {
  48. parts := strings.Split(fileId, ",")
  49. if len(parts) != 2 {
  50. return "", errors.New("Invalid fileId " + fileId)
  51. }
  52. serverUrl, lookupError := vc.LookupVolumeServerUrl(parts[0])
  53. if lookupError != nil {
  54. return "", lookupError
  55. }
  56. return serverUrl, nil
  57. }
  58. func (vc *vidMap) GetVidLocations(vid string) (locations []Location) {
  59. id, err := strconv.Atoi(vid)
  60. if err != nil {
  61. glog.V(1).Infof("Unknown volume id %s", vid)
  62. return nil
  63. }
  64. return vc.GetLocations(uint32(id))
  65. }
  66. func (vc *vidMap) GetLocations(vid uint32) (locations []Location) {
  67. vc.RLock()
  68. defer vc.RUnlock()
  69. return vc.vid2Locations[vid]
  70. }
  71. func (vc *vidMap) addLocation(vid uint32, location Location) {
  72. vc.Lock()
  73. defer vc.Unlock()
  74. locations, found := vc.vid2Locations[vid]
  75. if !found {
  76. vc.vid2Locations[vid] = []Location{location}
  77. return
  78. }
  79. for _, loc := range locations {
  80. if loc.Url == location.Url {
  81. return
  82. }
  83. }
  84. vc.vid2Locations[vid] = append(locations, location)
  85. }
  86. func (vc *vidMap) deleteLocation(vid uint32, location Location) {
  87. vc.Lock()
  88. defer vc.Unlock()
  89. locations, found := vc.vid2Locations[vid]
  90. if !found {
  91. return
  92. }
  93. for i, loc := range locations {
  94. if loc.Url == location.Url {
  95. vc.vid2Locations[vid] = append(locations[0:i], locations[i+1:]...)
  96. }
  97. }
  98. }