From f7adf1687f8c0e101fc585342700d15f422b96e9 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 29 Aug 2012 00:58:03 -0700 Subject: [PATCH] reduce duplicated code by using a tree of Node --- weed-fs/src/pkg/topology/capacity.go | 8 --- weed-fs/src/pkg/topology/data_center.go | 47 +----------------- weed-fs/src/pkg/topology/node.go | 66 +++++++++++++++++++------ weed-fs/src/pkg/topology/rack.go | 36 +------------- weed-fs/src/pkg/topology/server.go | 21 ++++++++ weed-fs/src/pkg/topology/topology.go | 53 +++----------------- 6 files changed, 80 insertions(+), 151 deletions(-) delete mode 100644 weed-fs/src/pkg/topology/capacity.go create mode 100644 weed-fs/src/pkg/topology/server.go diff --git a/weed-fs/src/pkg/topology/capacity.go b/weed-fs/src/pkg/topology/capacity.go deleted file mode 100644 index 57ba02cd3..000000000 --- a/weed-fs/src/pkg/topology/capacity.go +++ /dev/null @@ -1,8 +0,0 @@ -package topology - -import () - -type StorageCapacity struct { - countVolumeCount int - maxVolumeCount int -} diff --git a/weed-fs/src/pkg/topology/data_center.go b/weed-fs/src/pkg/topology/data_center.go index cffcdec4a..df6500732 100644 --- a/weed-fs/src/pkg/topology/data_center.go +++ b/weed-fs/src/pkg/topology/data_center.go @@ -1,54 +1,9 @@ package topology import ( - "pkg/storage" ) -type DataCenterId string type DataCenter struct { - Id DataCenterId - racks map[RackId]*Rack + Node ipRange IpRange - - //transient - allocation StorageCapacity - topology *Topology -} - -func (d *DataCenter) CreateOneVolume(r int, vid storage.VolumeId) storage.VolumeId { - for _, rack := range d.racks { - freeSpace := rack.allocation.maxVolumeCount - rack.allocation.countVolumeCount - if r > freeSpace { - r -= freeSpace - } else { - rack.CreateOneVolume(r, vid) - } - } - return vid -} -func (d *DataCenter) AddVolume(rack *Rack, v *storage.VolumeInfo) { - d.allocation.countVolumeCount += 1 - d.topology.AddVolume(d, v) -} -func (d *DataCenter) AddNode(rack *Rack, n *Node) { - d.allocation.countVolumeCount += len(n.volumes) - d.allocation.maxVolumeCount += n.maxVolumeCount - d.topology.AddNode(d, n) -} -func (d *DataCenter) RemoveNode(rack *Rack, n *Node) { - d.allocation.countVolumeCount -= len(n.volumes) - d.allocation.maxVolumeCount -= n.maxVolumeCount - d.topology.RemoveNode(d, n) -} -func (d *DataCenter) AddRack(rack *Rack) { - d.racks[rack.Id] = rack - d.allocation.countVolumeCount += rack.allocation.countVolumeCount - d.allocation.maxVolumeCount += rack.allocation.maxVolumeCount - d.topology.AddRack(d, rack) -} -func (d *DataCenter) RemoveRack(rack *Rack) { - delete(d.racks, rack.Id) - d.allocation.countVolumeCount -= rack.allocation.countVolumeCount - d.allocation.maxVolumeCount -= rack.allocation.maxVolumeCount - d.topology.AddRack(d, rack) } diff --git a/weed-fs/src/pkg/topology/node.go b/weed-fs/src/pkg/topology/node.go index 9b4ab27b5..15075e0ca 100644 --- a/weed-fs/src/pkg/topology/node.go +++ b/weed-fs/src/pkg/topology/node.go @@ -1,25 +1,61 @@ package topology import ( - "pkg/storage" + "pkg/storage" ) type NodeId string type Node struct { - volumes map[storage.VolumeId]*storage.VolumeInfo - maxVolumeCount int - Ip NodeId - Port int - PublicUrl string - - //transient - rack *Rack + id NodeId + countVolumeCount int + reservedVolumeCount int + maxVolumeCount int + parent *Node + children map[NodeId]*Node + isLeaf bool } -func (n *Node) CreateOneVolume(r int, vid storage.VolumeId) storage.VolumeId { - n.AddVolume(&storage.VolumeInfo{Id:vid, Size: 32*1024*1024*1024}) - return vid + +func (n *Node) ReserveOneVolume(r int, vid storage.VolumeId) bool { + for _, node := range n.children { + freeSpace := node.maxVolumeCount - node.countVolumeCount - node.reservedVolumeCount + if r > freeSpace { + r -= freeSpace + } else { + if node.ReserveOneVolume(r, vid) { + node.reservedVolumeCount++ + return true + } else { + return false + } + } + } + return false } -func (n *Node) AddVolume(v *storage.VolumeInfo){ - n.volumes[v.Id] = v - n.rack.AddVolume(n,v) + +func (n *Node) AddVolume(v *storage.VolumeInfo) { + n.countVolumeCount++ + if n.reservedVolumeCount > 0 { //if reserved + n.reservedVolumeCount-- + } + if n.parent != nil { + n.parent.AddVolume(v) + } +} + +func (n *Node) AddNode(node *Node) { + n.children[node.id] = node + n.countVolumeCount += node.countVolumeCount + n.maxVolumeCount += node.maxVolumeCount + if n.parent != nil { + n.parent.AddNode(node) + } +} + +func (n *Node) RemoveNode(node *Node) { + delete(n.children, node.id) + n.countVolumeCount -= node.countVolumeCount + n.maxVolumeCount -= node.maxVolumeCount + if n.parent != nil { + n.parent.RemoveNode(node) + } } diff --git a/weed-fs/src/pkg/topology/rack.go b/weed-fs/src/pkg/topology/rack.go index 0ed0600c5..3bcea6de5 100644 --- a/weed-fs/src/pkg/topology/rack.go +++ b/weed-fs/src/pkg/topology/rack.go @@ -1,43 +1,9 @@ package topology import ( - "pkg/storage" ) -type RackId uint32 type Rack struct { - Id RackId - nodes map[NodeId]*Node + Node ipRange IpRange - - //transient - allocation StorageCapacity - dataCenter *DataCenter -} -func (rack *Rack) CreateOneVolume(r int, vid storage.VolumeId) storage.VolumeId { - for _, node := range rack.nodes { - freeSpace := node.maxVolumeCount - len(node.volumes) - if r > freeSpace { - r -= freeSpace - } else { - node.CreateOneVolume(r, vid) - } - } - return vid -} -func (r *Rack) AddVolume(n *Node, v *storage.VolumeInfo){ - r.allocation.countVolumeCount += 1 - r.dataCenter.AddVolume(r,v) -} -func (r *Rack) AddNode(n *Node){ - r.nodes[n.Ip] = n - r.allocation.countVolumeCount += len(n.volumes) - r.allocation.maxVolumeCount += n.maxVolumeCount - r.dataCenter.AddNode(r,n) -} -func (r *Rack) RemoveNode(n *Node){ - delete(r.nodes,n.Ip) - r.allocation.countVolumeCount -= len(n.volumes) - r.allocation.maxVolumeCount -= n.maxVolumeCount - r.dataCenter.RemoveNode(r,n) } diff --git a/weed-fs/src/pkg/topology/server.go b/weed-fs/src/pkg/topology/server.go new file mode 100644 index 000000000..802aaebbb --- /dev/null +++ b/weed-fs/src/pkg/topology/server.go @@ -0,0 +1,21 @@ +package topology + +import ( + "pkg/storage" +) + +type Server struct { + Node + volumes map[storage.VolumeId]*storage.VolumeInfo + Ip NodeId + Port int + PublicUrl string +} +func (s *Server) CreateOneVolume(r int, vid storage.VolumeId) storage.VolumeId { + s.AddVolume(&storage.VolumeInfo{Id:vid, Size: 32*1024*1024*1024}) + return vid +} +func (s *Server) AddVolume(v *storage.VolumeInfo){ + s.volumes[v.Id] = v + s.Node.AddVolume(v) +} diff --git a/weed-fs/src/pkg/topology/topology.go b/weed-fs/src/pkg/topology/topology.go index ffeff784c..05f603af3 100644 --- a/weed-fs/src/pkg/topology/topology.go +++ b/weed-fs/src/pkg/topology/topology.go @@ -1,61 +1,20 @@ package topology import ( - "math/rand" + "math/rand" "pkg/storage" ) type Topology struct { - datacenters map[DataCenterId]*DataCenter - - //transient - allocation StorageCapacity + Node } -//FIXME -func (t *Topology) RandomlyCreateOneVolume() storage.VolumeId { - r := rand.Intn(t.allocation.maxVolumeCount-t.allocation.countVolumeCount) +func (t *Topology) RandomlyCreateOneVolume() (bool,storage.VolumeId) { + r := rand.Intn(t.Node.maxVolumeCount-t.Node.countVolumeCount-t.Node.reservedVolumeCount) vid := t.nextVolumeId() - for _, d := range t.datacenters { - freeSpace := d.allocation.maxVolumeCount-d.allocation.countVolumeCount - if r>freeSpace{ - r -= freeSpace - }else{ - d.CreateOneVolume(r, vid) - return vid - } - } - return storage.VolumeId(0) //FIXME + return t.Node.ReserveOneVolume(r,vid), vid } + func (t *Topology) nextVolumeId() storage.VolumeId { return storage.VolumeId(0) } -func (t *Topology) AddVolume(d *DataCenter, v *storage.VolumeInfo) { - t.allocation.countVolumeCount += 1 -} -func (t *Topology) AddNode(d *DataCenter, n *Node){ - t.allocation.countVolumeCount += len(n.volumes) - t.allocation.maxVolumeCount += n.maxVolumeCount -} -func (t *Topology) RemoveNode(d *DataCenter, n *Node){ - t.allocation.countVolumeCount -= len(n.volumes) - t.allocation.maxVolumeCount -= n.maxVolumeCount -} -func (t *Topology) AddRack(d *DataCenter, rack *Rack){ - t.allocation.countVolumeCount += rack.allocation.countVolumeCount - t.allocation.maxVolumeCount += rack.allocation.maxVolumeCount -} -func (t *Topology) RemoveRack(d *DataCenter, rack *Rack){ - t.allocation.countVolumeCount -= rack.allocation.countVolumeCount - t.allocation.maxVolumeCount -= rack.allocation.maxVolumeCount -} -func (t *Topology) AddDataCenter(d *DataCenter) { - t.datacenters[d.Id] = d - t.allocation.countVolumeCount += d.allocation.countVolumeCount - t.allocation.maxVolumeCount += d.allocation.maxVolumeCount -} -func (t *Topology) RemoveDataCenter(d *DataCenter) { - delete(t.datacenters,d.Id) - t.allocation.countVolumeCount -= d.allocation.countVolumeCount - t.allocation.maxVolumeCount -= d.allocation.maxVolumeCount -}