@ -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 |