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.

136 lines
2.9 KiB

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