|
@ -1,4 +1,5 @@ |
|
|
require "big" |
|
|
require "big" |
|
|
|
|
|
require "crystalline" |
|
|
|
|
|
|
|
|
module Crystal::Scatter |
|
|
module Crystal::Scatter |
|
|
|
|
|
|
|
@ -9,9 +10,10 @@ module Crystal::Scatter |
|
|
|
|
|
|
|
|
class Daemon(Ign,T) |
|
|
class Daemon(Ign,T) |
|
|
getter range_effector : Nil | Tuple(UInt64,UInt64) |
|
|
getter range_effector : Nil | Tuple(UInt64,UInt64) |
|
|
getter reach_at : T |
|
|
|
|
|
|
|
|
getter reach_at : T |
|
|
|
|
|
getter self_id : Int32 |
|
|
|
|
|
|
|
|
def initialize(@weight : UInt64 = 1) |
|
|
|
|
|
|
|
|
def initialize(@self_id, @weight : UInt64 = 1) |
|
|
@reach_at = T.new |
|
|
@reach_at = T.new |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
@ -27,7 +29,11 @@ module Crystal::Scatter |
|
|
@weight |
|
|
@weight |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def add(@weight, elems,@reach_at) |
|
|
|
|
|
|
|
|
def <=>(other : Daemon(Ign,T)) |
|
|
|
|
|
@self_id<=>other.self_id |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
def add(@weight,elems,@reach_at) |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def set_end |
|
|
def set_end |
|
@ -39,38 +45,55 @@ module Crystal::Scatter |
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
class Container(T,U) < Array(T) |
|
|
|
|
|
|
|
|
class Container(T,U,SelfT) |
|
|
|
|
|
@contents : Crystalline::Containers::RBTreeSet(T) |
|
|
|
|
|
getter self_id : Int32 |
|
|
|
|
|
|
|
|
|
|
|
def initialize(@self_id : Int32) |
|
|
|
|
|
@contents = SelfT.new |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
def <=>(other : Container(T,U,SelfT)) |
|
|
|
|
|
@self_id<=>other.self_id |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
def set_effectors(last_set : UInt64, split_rate : BigRational, total_weight : UInt64, split_ratio : BigRational) : UInt64 |
|
|
def set_effectors(last_set : UInt64, split_rate : BigRational, total_weight : UInt64, split_ratio : BigRational) : UInt64 |
|
|
split_rate *= size |
|
|
|
|
|
each do |elem| |
|
|
|
|
|
|
|
|
split_rate *= vi">@contents.size |
|
|
|
|
|
vi">@contents.each do |elem| |
|
|
last_set = elem.set_effectors(last_set, split_rate,total_weight,split_ratio) |
|
|
last_set = elem.set_effectors(last_set, split_rate,total_weight,split_ratio) |
|
|
end |
|
|
end |
|
|
return last_set |
|
|
return last_set |
|
|
end |
|
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
def first |
|
|
|
|
|
@contents.first.not_nil! |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
def last |
|
|
|
|
|
@contents.last.not_nil! |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
def set_end |
|
|
def set_end |
|
|
last.set_end |
|
|
|
|
|
|
|
|
vi">@contents.last.not_nil!.set_end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def get_weight : UInt64 |
|
|
def get_weight : UInt64 |
|
|
total : UInt64 = 0 |
|
|
total : UInt64 = 0 |
|
|
each do |elem| |
|
|
|
|
|
|
|
|
vi">@contents.each do |elem| |
|
|
total += elem.get_weight |
|
|
total += elem.get_weight |
|
|
end |
|
|
end |
|
|
return total |
|
|
return total |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def add(nweight, elems, reach_at) |
|
|
def add(nweight, elems, reach_at) |
|
|
if elems[0]==size |
|
|
|
|
|
push T.new |
|
|
|
|
|
elsif elems[0]>size |
|
|
|
|
|
raise ArgumentError.new("Tried to insert in an invalid position") |
|
|
|
|
|
end |
|
|
|
|
|
at(elems[0]).add(nweight, elems.skip(1), reach_at) |
|
|
|
|
|
|
|
|
if(!(@contents.has_key?(T.new(elems[0])))) |
|
|
|
|
|
@contents << T.new(elems[0]) |
|
|
|
|
|
end |
|
|
|
|
|
@contents.get(T.new(elems[0])).not_nil!.add(nweight, elems.skip(1), reach_at) |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def snapshot |
|
|
def snapshot |
|
|
each do |elem| |
|
|
|
|
|
|
|
|
vi">@contents.each do |elem| |
|
|
elem.snapshot do |x| |
|
|
elem.snapshot do |x| |
|
|
yield x |
|
|
yield x |
|
|
end |
|
|
end |
|
@ -78,24 +101,23 @@ module Crystal::Scatter |
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
class Server(U) < Container(Daemon(U,U),U) end |
|
|
|
|
|
|
|
|
class Server(U) < Container(Daemon(U,U),U,Crystalline::Containers::RBTreeSet(Daemon(U,U))) end |
|
|
|
|
|
|
|
|
class PSU(U) < Container(Server(U),U) end |
|
|
|
|
|
|
|
|
class PSU(U) < Container(Server(U),U,Crystalline::Containers::RBTreeSet(Server(U))) end |
|
|
|
|
|
|
|
|
class Rack(U) < Container(PSU(U),U) end |
|
|
|
|
|
|
|
|
class Rack(U) < Container(PSU(U),U,Crystalline::Containers::RBTreeSet(PSU(U))) end |
|
|
|
|
|
|
|
|
class Room(U) < Container(Rack(U),U) end |
|
|
|
|
|
|
|
|
class Room(U) < Container(Rack(U),U,Crystalline::Containers::RBTreeSet(Rack(U))) end |
|
|
|
|
|
|
|
|
class Datacenter(U) < Container(Room(U),U) end |
|
|
|
|
|
|
|
|
class Datacenter(U) < Container(Room(U),U,Crystalline::Containers::RBTreeSet(Room(U))) end |
|
|
|
|
|
|
|
|
class Root(U) < Container(Datacenter(U),U) end |
|
|
|
|
|
|
|
|
class Root(U) < Container(Datacenter(U),U,Crystalline::Containers::RBTreeSet(Datacenter(U))) end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
class RingGraph < Servers::Root(String) |
|
|
|
|
|
|
|
|
class RingGraph < Servers::Root(String) |
|
|
def generate_ring(split_ratio : BigRational) |
|
|
def generate_ring(split_ratio : BigRational) |
|
|
set_effectors(UInt64::MAX, BigRational.new(1), get_weight, split_ratio) |
|
|
set_effectors(UInt64::MAX, BigRational.new(1), get_weight, split_ratio) |
|
|
set_end |
|
|
set_end |
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
end |
|
|
end |