[ create a new paste ] login | about

Link: http://codepad.org/ceDyQ8lE    [ raw code | fork ]

D, pasted on Jan 21:
import std.stdio: writeln;
import std.conv: to, text;
import std.random: Random, uniform;
import std.algorithm: min, max;
import std.parallelism: task;
import core.thread: Thread;
import core.sync.mutex: Mutex;
import core.time: dur;

final class Buckets {
    alias TBucketValue = uint;

    private final struct Bucket {
        TBucketValue value;
        Mutex mtx;
    }

    private Bucket[] buckets;

    public this(in uint count) {
        this.buckets.length = count;
        foreach (ref b; buckets)
            b = Bucket(uniform(0, 100), new Mutex());
    }

    public TBucketValue get(in uint index) const pure nothrow {
        return buckets[index].value;
    }

    public void transfer(in uint from, in uint to,
                         in TBucketValue amount) {
        buckets[min(from, to)].mtx.lock();
        buckets[max(from, to)].mtx.lock();
        immutable realAmount = min(buckets[from].value, amount);
        buckets[from].value -= realAmount;
        buckets[to  ].value += realAmount;
        buckets[min(from, to)].mtx.unlock();
        buckets[max(from, to)].mtx.unlock();
    }

    @property size_t length() const pure nothrow {
        return this.buckets.length;
    }

    void toString(in void delegate(const(char)[]) sink) {
        TBucketValue sum = 0;
        sink("(");
        foreach (ref b; buckets) {
            b.mtx.lock();
            sum += b.value;
            sink(text(b.value));
            sink(" ");
        }
        sink(") sum: ");
        sink(text(sum));
        foreach (ref b; buckets)
            b.mtx.unlock();
    }
}

void randomize(Buckets data) {
    immutable maxi = data.length - 1;

    while (true) {
        immutable i = uniform(0, maxi);
        immutable j = uniform(0, maxi);
        immutable amount = uniform(0, 20);
        data.transfer(i, j, amount);
    }
}

void equalize(Buckets data) {
    immutable maxi = data.length - 1;

    while (true) {
        immutable i = uniform(0, maxi);
        immutable j = uniform(0, maxi);
        immutable a = data.get(i);
        immutable b = data.get(j);
        if (a > b)
            data.transfer(i, j, (a - b) / 2);
        else
            data.transfer(j, i, (b - a) / 2);
    }
}

void display(Buckets data) {
    while (true) {
        writeln(data);
        Thread.sleep(dur!"seconds"(3));
    }
}

void main() {
    auto data = new Buckets(20);
    task!randomize(data).executeInNewThread();
    task!equalize(data).executeInNewThread();
    task!display(data).executeInNewThread();
}


Create a new paste based on this one


Comments: