| @ -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 | |||||
| @ -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 | |||||
| @ -0,0 +1 @@ | |||||
| language: crystal | |||||
| @ -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. | |||||
| @ -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 (<https://github.com/your-github-user/crystal-scatter/fork>) | |||||
| 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 | |||||
| @ -0,0 +1,9 @@ | |||||
| name: crystal-scatter | |||||
| version: 0.1.0 | |||||
| authors: | |||||
| - Ludovic 'Archivist' Lagouardette <lagouardette.ludovic@gmail.com> | |||||
| crystal: 0.25.0 | |||||
| license: MIT | |||||
| @ -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 | |||||
| @ -0,0 +1,2 @@ | |||||
| require "spec" | |||||
| require "../src/crystal-scatter" | |||||
| @ -0,0 +1,6 @@ | |||||
| require "./crystal-scatter/*" | |||||
| # TODO: Write documentation for `Crystal::Scatter` | |||||
| module Crystal::Scatter | |||||
| # TODO: Put your code here | |||||
| end | |||||
| @ -0,0 +1,9 @@ | |||||
| require "./ring.cr" | |||||
| module Crystal::Scatter | |||||
| class MetaRing | |||||
| end | |||||
| end | |||||
| @ -0,0 +1,11 @@ | |||||
| module Crystal::Scatter | |||||
| class Slice | |||||
| end | |||||
| class Ring | |||||
| end | |||||
| end | |||||
| @ -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 | |||||
| @ -0,0 +1,3 @@ | |||||
| module Crystal::Scatter | |||||
| VERSION = "0.1.0" | |||||
| end | |||||