c9d96c | 2015-08-20 | Henrik Grubbström (Grubba) | |
#pike __REAL_VERSION__
inherit .Scheduler;
|
0c4ea5 | 2015-08-22 | Martin Nilsson | |
|
c9d96c | 2015-08-20 | Henrik Grubbström (Grubba) | |
class Consumer
{
inherit ::this_program;
Consumer parent;
array(Consumer) children = ({});
float children_weight = 0.0;
int(0..) depth;
void update_quanta()
{
if (!parent) {
quanta = 1.0;
return;
}
float old_quanta = quanta;
quanta = parent->children_weight * parent->quanta / weight;
children->update_quanta();
pri += (quanta - old_quanta)/2.0;
adjust();
}
void `weight=(float|int new_weight)
{
if (new_weight == weight_) return;
parent->children_weight += new_weight - weight_;
weight_ = new_weight;
parent->children->update_quanta();
}
float|int `weight()
{
return weight_;
}
protected void create(int|float weight, mixed v, Consumer|void parent)
{
weight_ = weight;
value = v;
parent = this_program::parent = parent || root;
if (parent) {
parent->children += ({ this });
parent->children_weight += weight;
depth = parent->depth + 1;
pri = parent->pri - parent->quanta/2.0;
offset = parent->offset;
parent->children->update_quanta();
} else {
quanta = 1.0;
pri = 0.5;
}
}
void set_depth(int new_depth)
{
if (depth == new_depth) return;
depth = new_depth;
foreach(children, Consumer c) {
c->set_depth(depth + 1);
}
adjust();
}
void consume_down(float delta)
{
foreach(children, Consumer c) {
c->consume_down(delta * c->weight / children_weight);
}
::consume(delta);
}
void consume_up(float delta)
{
::consume(delta);
if (parent) {
parent->consume_up(delta);
}
}
void consume(float delta)
{
consume_down(delta);
if (parent) {
parent->consume_up(delta);
}
}
|
dc9373 | 2015-08-22 | Martin Nilsson | |
|
c9d96c | 2015-08-20 | Henrik Grubbström (Grubba) | |
void set_parent(Consumer new_parent, int|float weight)
{
if (!new_parent) new_parent = root;
if (new_parent == parent) {
this_program::weight = weight;
return;
}
Consumer npp = new_parent;
while (npp) {
if (npp == this) {
new_parent->set_parent(parent, weight_);
break;
}
npp = npp->parent;
}
parent->children_weight -= weight_;
parent->children -= ({ this });
parent->children->update_quanta();
parent = new_parent;
weight_ = weight;
parent->children += ({ this });
parent->children_weight += weight;
set_depth(parent->depth + 1);
parent->children->update_quanta();
float parent_pri = parent->pri + parent->offset - offset;
if (parent_pri > pri) {
consume_down((parent_pri - pri) / quanta);
}
}
void reparent_siblings()
{
if (sizeof(parent->children) == 1) return;
float weight_factor = children_weight/weight;
foreach(parent->children, Consumer c) {
if (c == this) continue;
c->set_parent(this, c->weight * weight_factor);
}
}
void detach()
{
if (state & STATE_ACTIVE) {
remove(this);
}
Consumer parent = this_program::parent;
this_program::parent = UNDEFINED;
parent->children -= ({ this });
if (sizeof(children)) {
parent->children += children;
foreach(children, Consumer c) {
c->parent = parent;
c->weight *= weight/children_weight;
parent->children_weight += c->weight;
}
children->set_depth(parent->depth + 1);
children = ({});
}
parent->children_weight -= weight;
parent->children->update_quanta();
}
|
c071bc | 2017-11-05 | Henrik Grubbström (Grubba) | | protected void _destruct()
|
c9d96c | 2015-08-20 | Henrik Grubbström (Grubba) | | {
if (parent) {
detach();
} else {
foreach(children, Consumer c) {
c->parent = UNDEFINED;
c->set_depth(depth);
}
}
}
protected int `<(object o)
{
if (pri == o->pri) {
return depth < o->depth;
}
return pri<o->pri;
}
protected int `>(object o)
{
if (pri == o->pri) {
return depth > o->depth;
}
return pri>o->pri;
}
}
variant Consumer add(int|float weight, mixed val, Consumer parent)
{
return add(Consumer(weight, val, parent));
}
Consumer root = Consumer(1.0, "root");
protected string _sprintf(int c)
{
if (c != 'O') return UNDEFINED;
Stdio.Buffer buf = Stdio.Buffer("ADT.TreeScheduler(\n");
.Stack todo = .Stack();
todo->push(0);
todo->push(root);
Consumer child;
while (child = todo->pop()) {
buf->sprintf(" %*s%O\n", child->depth * 2, "", child);
foreach(reverse(child->children), Consumer cc) {
todo->push(cc);
}
}
buf->add(")");
return (string)buf;
}
|
c071bc | 2017-11-05 | Henrik Grubbström (Grubba) | | protected void _destruct()
|
c9d96c | 2015-08-20 | Henrik Grubbström (Grubba) | | {
.Stack todo = .Stack();
todo->push(0);
todo->push(root);
root = UNDEFINED;
Consumer child;
while (child = todo->pop()) {
foreach(child->children, Consumer cc) {
todo->push(cc);
}
child->children = ({});
child->parent = UNDEFINED;
destruct(child);
}
}
|