diff options
| author | Chris Lu <chrislusf@users.noreply.github.com> | 2018-07-28 21:03:29 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-07-28 21:03:29 -0700 |
| commit | 452bd0b01393e53e958fb9825bf1f27e6b3522df (patch) | |
| tree | e1a61e592118f9696b7f51501d3b3fd0f6c3eeb5 /weed/wdclient/vid_map.go | |
| parent | 97603d6e176dd2b9f2aebd9f6122a8c60481463a (diff) | |
| parent | d3205a007071f26587affb416f71b5c63854b863 (diff) | |
| download | seaweedfs-452bd0b01393e53e958fb9825bf1f27e6b3522df.tar.xz seaweedfs-452bd0b01393e53e958fb9825bf1f27e6b3522df.zip | |
Merge pull request #702 from chrislusf/add_topo_listener
Add volume id location change listener
Diffstat (limited to 'weed/wdclient/vid_map.go')
| -rw-r--r-- | weed/wdclient/vid_map.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/weed/wdclient/vid_map.go b/weed/wdclient/vid_map.go new file mode 100644 index 000000000..2f56b8fce --- /dev/null +++ b/weed/wdclient/vid_map.go @@ -0,0 +1,99 @@ +package wdclient + +import ( + "errors" + "fmt" + "math/rand" + "strconv" + "strings" + "sync" + + "github.com/chrislusf/seaweedfs/weed/glog" +) + +type Location struct { + Url string `json:"url,omitempty"` + PublicUrl string `json:"publicUrl,omitempty"` +} + +type vidMap struct { + sync.RWMutex + vid2Locations map[uint32][]Location +} + +func newVidMap() vidMap { + return vidMap{ + vid2Locations: make(map[uint32][]Location), + } +} + +func (vc *vidMap) LookupVolumeServerUrl(vid string) (serverUrl string, err error) { + id, err := strconv.Atoi(vid) + if err != nil { + glog.V(1).Infof("Unknown volume id %s", vid) + return "", err + } + + locations := vc.GetLocations(uint32(id)) + if len(locations) == 0 { + return "", fmt.Errorf("volume %d not found", id) + } + + return locations[rand.Intn(len(locations))].Url, nil +} + +func (vc *vidMap) LookupFileId(fileId string) (fullUrl string, err error) { + parts := strings.Split(fileId, ",") + if len(parts) != 2 { + return "", errors.New("Invalid fileId " + fileId) + } + serverUrl, lookupError := vc.LookupVolumeServerUrl(parts[0]) + if lookupError != nil { + return "", lookupError + } + return "http://" + serverUrl + "/" + fileId, nil +} + +func (vc *vidMap) GetLocations(vid uint32) (locations []Location) { + vc.RLock() + defer vc.RUnlock() + + return vc.vid2Locations[vid] +} + +func (vc *vidMap) addLocation(vid uint32, location Location) { + vc.Lock() + defer vc.Unlock() + + locations, found := vc.vid2Locations[vid] + if !found { + vc.vid2Locations[vid] = []Location{location} + return + } + + for _, loc := range locations { + if loc.Url == location.Url { + return + } + } + + vc.vid2Locations[vid] = append(locations, location) + +} + +func (vc *vidMap) deleteLocation(vid uint32, location Location) { + vc.Lock() + defer vc.Unlock() + + locations, found := vc.vid2Locations[vid] + if !found { + return + } + + for i, loc := range locations { + if loc.Url == location.Url { + vc.vid2Locations[vid] = append(locations[0:i], locations[i+1:]...) + } + } + +} |
