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.
 

123 lines
3.6 KiB

require "big"
require "crystalline"
module Crystal::Scatter
module Servers
def last_effector_end : UInt64
UInt64.MAX
end
class Daemon(Ign,T)
getter range_effector : Nil | Tuple(UInt64,UInt64)
getter reach_at : T
getter self_id : Int32
def initialize(@self_id, @weight : UInt64 = 1)
@reach_at = T.new
end
def set_effectors(last_set : UInt64, split_rate : BigRational, total_weight : UInt64,split_ratio : BigRational) : UInt64
@range_effector = Tuple.new(
last_set+1,
(last_set+1+UInt64::MAX*(split_rate.inv*split_ratio + (@weight*(1-split_ratio))/total_weight)).round.to_big_f.to_u64
)
return @range_effector.not_nil!.[1]
end
def get_weight : UInt64
@weight
end
def <=>(other : Daemon(Ign,T))
@self_id<=>other.self_id
end
def add(@weight,elems,@reach_at)
end
def set_end
@range_effector=Tuple.new(@range_effector.not_nil!.[0],UInt64::MAX)
end
def snapshot
yield self
end
end
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
split_rate *= @contents.size
@contents.each do |elem|
last_set = elem.set_effectors(last_set, split_rate,total_weight,split_ratio)
end
return last_set
end
def first
@contents.first.not_nil!
end
def last
@contents.last.not_nil!
end
def set_end
@contents.last.not_nil!.set_end
end
def get_weight : UInt64
total : UInt64 = 0
@contents.each do |elem|
total += elem.get_weight
end
return total
end
def add(nweight, elems, 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
def snapshot
@contents.each do |elem|
elem.snapshot do |x|
yield x
end
end
end
end
class Server(U) < Container(Daemon(U,U),U,Crystalline::Containers::RBTreeSet(Daemon(U,U))) end
class PSU(U) < Container(Server(U),U,Crystalline::Containers::RBTreeSet(Server(U))) end
class Rack(U) < Container(PSU(U),U,Crystalline::Containers::RBTreeSet(PSU(U))) end
class Room(U) < Container(Rack(U),U,Crystalline::Containers::RBTreeSet(Rack(U))) end
class Datacenter(U) < Container(Room(U),U,Crystalline::Containers::RBTreeSet(Room(U))) end
class Root(U) < Container(Datacenter(U),U,Crystalline::Containers::RBTreeSet(Datacenter(U))) end
end
class RingGraph < Servers::Root(String)
def generate_ring(split_ratio : BigRational)
set_effectors(UInt64::MAX, BigRational.new(1), get_weight, split_ratio)
set_end
end
end
end