Chris Lu
12 years ago
7 changed files with 337 additions and 16 deletions
-
74weed-fs/src/pkg/replication/volume_growth.go
-
129weed-fs/src/pkg/replication/volume_growth_test.go
-
20weed-fs/src/pkg/topology/node.go
-
69weed-fs/src/pkg/topology/node_list.go
-
39weed-fs/src/pkg/topology/node_list_test.go
-
5weed-fs/src/pkg/topology/topo_test.go
-
17weed-fs/src/pkg/topology/topology.go
@ -0,0 +1,129 @@ |
|||
package replication |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"fmt" |
|||
"math/rand" |
|||
"pkg/storage" |
|||
"pkg/topology" |
|||
"testing" |
|||
"time" |
|||
) |
|||
|
|||
var topologyLayout = ` |
|||
{ |
|||
"dc1":{ |
|||
"rack1":{ |
|||
"server1":{ |
|||
"volumes":[ |
|||
{"id":1, "size":12312}, |
|||
{"id":2, "size":12312}, |
|||
{"id":3, "size":12312} |
|||
], |
|||
"limit":3 |
|||
}, |
|||
"server2":{ |
|||
"volumes":[ |
|||
{"id":4, "size":12312}, |
|||
{"id":5, "size":12312}, |
|||
{"id":6, "size":12312} |
|||
], |
|||
"limit":10 |
|||
} |
|||
}, |
|||
"rack2":{ |
|||
"server1":{ |
|||
"volumes":[ |
|||
{"id":4, "size":12312}, |
|||
{"id":5, "size":12312}, |
|||
{"id":6, "size":12312} |
|||
], |
|||
"limit":4 |
|||
}, |
|||
"server2":{ |
|||
"volumes":[], |
|||
"limit":4 |
|||
}, |
|||
"server3":{ |
|||
"volumes":[ |
|||
{"id":2, "size":12312}, |
|||
{"id":3, "size":12312}, |
|||
{"id":4, "size":12312} |
|||
], |
|||
"limit":2 |
|||
} |
|||
} |
|||
}, |
|||
"dc2":{ |
|||
}, |
|||
"dc3":{ |
|||
"rack2":{ |
|||
"server1":{ |
|||
"volumes":[ |
|||
{"id":1, "size":12312}, |
|||
{"id":3, "size":12312}, |
|||
{"id":5, "size":12312} |
|||
], |
|||
"limit":4 |
|||
} |
|||
} |
|||
} |
|||
} |
|||
` |
|||
|
|||
func setup(topologyLayout string) *topology.Topology { |
|||
var data interface{} |
|||
err := json.Unmarshal([]byte(topologyLayout), &data) |
|||
if err != nil { |
|||
fmt.Println("error:", err) |
|||
} |
|||
fmt.Println("data:", data) |
|||
|
|||
//need to connect all nodes first before server adding volumes
|
|||
topo := topology.NewTopology("mynetwork") |
|||
mTopology := data.(map[string]interface{}) |
|||
for dcKey, dcValue := range mTopology { |
|||
dc := topology.NewDataCenter(dcKey) |
|||
dcMap := dcValue.(map[string]interface{}) |
|||
topo.LinkChildNode(dc) |
|||
for rackKey, rackValue := range dcMap { |
|||
rack := topology.NewRack(rackKey) |
|||
rackMap := rackValue.(map[string]interface{}) |
|||
dc.LinkChildNode(rack) |
|||
for serverKey, serverValue := range rackMap { |
|||
server := topology.NewServer(serverKey) |
|||
serverMap := serverValue.(map[string]interface{}) |
|||
rack.LinkChildNode(server) |
|||
for _, v := range serverMap["volumes"].([]interface{}) { |
|||
m := v.(map[string]interface{}) |
|||
vi := &storage.VolumeInfo{Id: storage.VolumeId(int64(m["id"].(float64))), Size: int64(m["size"].(float64))} |
|||
server.AddVolume(vi) |
|||
} |
|||
server.UpAdjustMaxVolumeCountDelta(int(serverMap["limit"].(float64))) |
|||
} |
|||
} |
|||
} |
|||
|
|||
fmt.Println("topology:", *topo) |
|||
|
|||
return topo |
|||
} |
|||
|
|||
func TestRemoveDataCenter(t *testing.T) { |
|||
topo := setup(topologyLayout) |
|||
topo.UnlinkChildNode(topology.NodeId("dc2")) |
|||
if topo.GetActiveVolumeCount() != 15 { |
|||
t.Fail() |
|||
} |
|||
topo.UnlinkChildNode(topology.NodeId("dc3")) |
|||
if topo.GetActiveVolumeCount() != 12 { |
|||
t.Fail() |
|||
} |
|||
} |
|||
|
|||
func TestReserveOneVolume(t *testing.T) { |
|||
topo := setup(topologyLayout) |
|||
rand.Seed(time.Now().UnixNano()) |
|||
vg:=&VolumeGrowth{copy1factor:3,copy2factor:2,copy3factor:1,copyAll:4} |
|||
vg.GrowVolumeCopy(20,topo) |
|||
} |
@ -0,0 +1,69 @@ |
|||
package topology |
|||
|
|||
import ( |
|||
"fmt" |
|||
"math/rand" |
|||
"pkg/storage" |
|||
) |
|||
|
|||
type NodeList struct { |
|||
nodes map[NodeId]Node |
|||
except map[string]Node |
|||
} |
|||
|
|||
func NewNodeList(nodes map[NodeId]Node, except map[string]Node) *NodeList { |
|||
m := make(map[NodeId]Node, len(nodes)-len(except)) |
|||
for _, n := range nodes { |
|||
if except[n.String()] == nil { |
|||
m[n.Id()] = n |
|||
} |
|||
} |
|||
nl := &NodeList{nodes: m} |
|||
return nl |
|||
} |
|||
|
|||
func (nl *NodeList) FreeSpace() int { |
|||
freeSpace := 0 |
|||
for _, n := range nl.nodes { |
|||
freeSpace += n.FreeSpace() |
|||
} |
|||
return freeSpace |
|||
} |
|||
|
|||
func (nl *NodeList) RandomlyPickN(n int) ([]Node, bool) { |
|||
var list []Node |
|||
for _, n := range nl.nodes { |
|||
if n.FreeSpace() > 0 { |
|||
list = append(list, n) |
|||
} |
|||
} |
|||
if n > len(list){ |
|||
return nil,false |
|||
} |
|||
for i := n; i > 0; i-- { |
|||
r := rand.Intn(i) |
|||
t := list[r] |
|||
list[r] = list[i-1] |
|||
list[i-1] = t |
|||
} |
|||
return list[len(list)-n:], true |
|||
} |
|||
|
|||
func (nl *NodeList) ReserveOneVolume(randomVolumeIndex int, vid storage.VolumeId) (bool, *Server) { |
|||
for _, node := range nl.nodes { |
|||
freeSpace := node.FreeSpace() |
|||
if randomVolumeIndex >= freeSpace { |
|||
randomVolumeIndex -= freeSpace |
|||
} else { |
|||
if node.IsServer() && node.FreeSpace() > 0 { |
|||
fmt.Println("vid =", vid, " assigned to node =", node, ", freeSpace =", node.FreeSpace()) |
|||
return true, node.(*Server) |
|||
} |
|||
children := node.Children() |
|||
newNodeList := NewNodeList(children, nl.except) |
|||
return newNodeList.ReserveOneVolume(randomVolumeIndex, vid) |
|||
} |
|||
} |
|||
return false, nil |
|||
|
|||
} |
@ -0,0 +1,39 @@ |
|||
package topology |
|||
|
|||
import ( |
|||
"strconv" |
|||
"testing" |
|||
_ "fmt" |
|||
) |
|||
|
|||
func TestXYZ(t *testing.T) { |
|||
topo := NewTopology("topo") |
|||
for i := 0; i < 5; i++ { |
|||
dc := NewDataCenter("dc" + strconv.Itoa(i)) |
|||
dc.activeVolumeCount = i |
|||
dc.maxVolumeCount = 5 |
|||
topo.LinkChildNode(dc) |
|||
} |
|||
nl := NewNodeList(topo.Children(),nil) |
|||
|
|||
picked, ret := nl.RandomlyPickN(1) |
|||
if !ret || len(picked)!=1 { |
|||
t.Errorf("need to randomly pick 1 node") |
|||
} |
|||
|
|||
picked, ret = nl.RandomlyPickN(4) |
|||
if !ret || len(picked)!=4 { |
|||
t.Errorf("need to randomly pick 4 nodes") |
|||
} |
|||
|
|||
picked, ret = nl.RandomlyPickN(5) |
|||
if !ret || len(picked)!=5 { |
|||
t.Errorf("need to randomly pick 5 nodes") |
|||
} |
|||
|
|||
picked, ret = nl.RandomlyPickN(6) |
|||
if ret || len(picked)!=0 { |
|||
t.Errorf("can not randomly pick 6 nodes:", ret, picked) |
|||
} |
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue