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.
 

88 lines
2.6 KiB

require "big"
module Crystal::Scatter
module Servers
def last_effector_end : UInt64
UInt64.MAX
end
class Daemon(Ign,T)
getter range_effector : Nil | Tuple(UInt64,UInt64)
def initialize(@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 add(@weight, elems,@reach_at)
end
def set_end
@range_effector=Tuple.new(@range_effector.not_nil!.[0],UInt64::MAX)
end
end
class Container(T,U) < Array(T)
def set_effectors(last_set : UInt64, split_rate : BigRational, total_weight : UInt64, split_ratio : BigRational) : UInt64
split_rate *= size
each do |elem|
last_set = elem.set_effectors(last_set, split_rate,total_weight,split_ratio)
end
return last_set
end
def set_end
last.set_end
end
def get_weight : UInt64
total : UInt64 = 0
each do |elem|
total += elem.get_weight
end
return total
end
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)
end
end
class Server(U) < Container(Daemon(U,U),U) end
class PSU(U) < Container(Server(U),U) end
class Rack(U) < Container(PSU(U),U) end
class Room(U) < Container(Rack(U),U) end
class Datacenter(U) < Container(Room(U),U) end
class Root(U) < Container(Datacenter(U),U) end
end
class RingGraph(T) < Servers::Root(T)
def generate_ring(split_ratio : BigRational)
set_effectors(UInt64::MAX, BigRational.new(1), get_weight, split_ratio)
set_end
end
end
end