commit 6701694d99cbedf8ee8ef9d1a65912cccfa64a3b Author: Archivist Date: Thu Aug 9 19:45:50 2018 +0200 RingGraph works diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..163eb75 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*.cr] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e29dae7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +/docs/ +/lib/ +/bin/ +/.shards/ +*.dwarf + +# Libraries don't need dependency lock +# Dependencies will be locked in application that uses them +/shard.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ffc7b6a --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: crystal diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fc89b5b --- /dev/null +++ b/LICENSE @@ -0,0 +1,47 @@ +Copyright (c) 2018 NekoIT + +This document refers NekoIT EIRL as "the holder". + +This document refers the repository this file is found and +its contents in as "the software". + +"Compiled form" of the software refers to any transformation +of the software or a modified version of the software resulting +in a modified yet semantically equivalent repository or file. + +"Modified version" refers to any distinct part of the software +or to an altered version of the software. + +The software is provided as sole demonstration of its source +code, and shall not be used for the purposes listed below +without explicit, written authorization from the holder. + +The purposes the software is prohibited for use are: + +* use by a company for commercial or non-commercial purposes +excluded providing insight of eventual flaws or issues of the +software + +* use by an individual or company for advertizing or promotion +of their own products or contents, excluded for the case of +individuals for demonstrating engagement in open source +software development + +* edition of a commercial product explicitly depending on the +software in either of its forms + +The software is prohibited from being redistributed unless +specified by a written notice from the holder. + +Redistribution of modified versions of the software or compiled +forms of the software is prohibited unless specified by a written +notice from the holder. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..40ba337 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# crystal-scatter + +TODO: Write a description here + +## Installation + +Add this to your application's `shard.yml`: + +```yaml +dependencies: + crystal-scatter: + github: your-github-user/crystal-scatter +``` + +## Usage + +```crystal +require "crystal-scatter" +``` + +TODO: Write usage instructions here + +## Development + +TODO: Write development instructions here + +## Contributing + +1. Fork it () +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create a new Pull Request + +## Contributors + +- [your-github-user](https://github.com/your-github-user) Ludovic 'Archivist' Lagouardette - creator, maintainer diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..bb5b530 --- /dev/null +++ b/shard.yml @@ -0,0 +1,9 @@ +name: crystal-scatter +version: 0.1.0 + +authors: + - Ludovic 'Archivist' Lagouardette + +crystal: 0.25.0 + +license: MIT diff --git a/spec/crystal-scatter_spec.cr b/spec/crystal-scatter_spec.cr new file mode 100644 index 0000000..52f4997 --- /dev/null +++ b/spec/crystal-scatter_spec.cr @@ -0,0 +1,16 @@ +require "./spec_helper" + +describe Crystal::Scatter do + # TODO: Write tests + + it "add elements" do + rg = Crystal::Scatter::RingGraph(String).new + rg.add(UInt64.new(1),[0,0,0,0,0,0],"OSD0") + rg.add(UInt64.new(1),[0,0,0,0,0,1],"OSD1") + rg.add(UInt64.new(1),[0,0,0,0,1,0],"OSD2") + rg.get_weight.should eq(3) + rg.generate_ring(BigRational.new(1)) + rg[0][0][0][0][0][0].range_effector.not_nil!.[0].should eq(0) + rg[0][0][0][0][1][0].range_effector.not_nil!.[1].should eq(UInt64::MAX) + end +end diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr new file mode 100644 index 0000000..596662f --- /dev/null +++ b/spec/spec_helper.cr @@ -0,0 +1,2 @@ +require "spec" +require "../src/crystal-scatter" diff --git a/src/crystal-scatter.cr b/src/crystal-scatter.cr new file mode 100644 index 0000000..c5dfa0d --- /dev/null +++ b/src/crystal-scatter.cr @@ -0,0 +1,6 @@ +require "./crystal-scatter/*" + +# TODO: Write documentation for `Crystal::Scatter` +module Crystal::Scatter + # TODO: Put your code here +end diff --git a/src/crystal-scatter/metaring.cr b/src/crystal-scatter/metaring.cr new file mode 100644 index 0000000..16690ed --- /dev/null +++ b/src/crystal-scatter/metaring.cr @@ -0,0 +1,9 @@ +require "./ring.cr" + +module Crystal::Scatter + + class MetaRing + + end + +end \ No newline at end of file diff --git a/src/crystal-scatter/ring.cr b/src/crystal-scatter/ring.cr new file mode 100644 index 0000000..b76140e --- /dev/null +++ b/src/crystal-scatter/ring.cr @@ -0,0 +1,11 @@ +module Crystal::Scatter + + class Slice + + end + + class Ring + + end + +end \ No newline at end of file diff --git a/src/crystal-scatter/ring_graph.cr b/src/crystal-scatter/ring_graph.cr new file mode 100644 index 0000000..e580508 --- /dev/null +++ b/src/crystal-scatter/ring_graph.cr @@ -0,0 +1,88 @@ +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 \ No newline at end of file diff --git a/src/crystal-scatter/version.cr b/src/crystal-scatter/version.cr new file mode 100644 index 0000000..0a45529 --- /dev/null +++ b/src/crystal-scatter/version.cr @@ -0,0 +1,3 @@ +module Crystal::Scatter + VERSION = "0.1.0" +end