<commit_before>class Handler {
    // probably more to come, could also be inherited and extended
    function prefetch, postfetch;
    array(Serialization.Atom) sdata;
    string stage;
    object msig, vsig, dsig;
    int dead = 0;
}

class StageIterator {
    inherit Iterator;

    array(string) mlist;
    string id;
    int index2, index3 = -1;
    object stage;

    Iterator _get_iterator() { return this; }

    void create(object stage, string method) {
	mlist = (method/"_");
	index2 = sizeof(mlist)-1;
	this_program::stage = stage;
	find_next();
    }

    void find_next() {
	for (;;) { 
	    if (index2 >=0 ) {
		if (--index3 >= 0) {
		    object h = stage->handler[id][index3];

		    if (h && !h->dead) { // race here
			return;	
		    } else {
			continue;
		    }
		} else {
		    id = mlist[0..index2]*"_";

		    index2--;
		    if (has_index(stage->handler, id)) {
			index3 = sizeof(stage->handler);
			continue;
		    }
		}
	    } else {
		id = UNDEFINED;
		return;
	    }
	}
    }

    mixed index() {
	return id;	
    }

    int(0..1) next() {
	find_next();

	return !!id;
    } 

    mixed value() {
	if (id && index3 > -1) return stage->handlers[id][index3];
	else return UNDEFINED;
    }

    .this_program `+=(int steps) {
	if (steps < 0) error("Cannot move backwards.\n");

	while (steps-- > 0 && id) {
	    find_next(); 
	}

	return this;
    }

    .this_program `+(int steps) {
	if (steps < 0) error("Cannot move backwards.\n");

	.this_program new = .this_program(stage, mlist*"_");
	new->index = index;
	new->id = id;

	new += steps;

	return new;
    }
}

class Stage {
    mapping(string:array(object)) handler = ([]);

    void create() {
    }

    .StageIterator get_iterator(string method) {
	return .StageIterator(this, method);
    }

    void add_handler(object h, string base) {
	if (!handler[base]) {
	    handler[base] = ({ });
	    set_weak_flag(handler[base], Pike.WEAK_VALUES);
	}

	handler[base] += ({ h });
    }
}

mapping(int:object) handler = ([]);
mapping(string:object) stages = ([]);

int get_new_id() {
    int i;
    while (has_index(handler, i = random(Int.NATIVE_MAX)));

    return i;
}

int add_method(mapping specs, object child) {<commit_msg>special start stage<commit_after>class Handler {
    // probably more to come, could also be inherited and extended
    function prefetch, postfetch;
    array(Serialization.Atom) sdata;
    string stage;
    object msig, vsig, dsig;
    int dead = 0;
}

class StageIterator {
    inherit Iterator;

    array(string) mlist;
    string id;
    int index2, index3 = -1;
    object stage;

    Iterator _get_iterator() { return this; }

    void create(object stage, string method) {
	mlist = (method/"_");
	index2 = sizeof(mlist)-1;
	this_program::stage = stage;
	find_next();
    }

    void find_next() {
	for (;;) { 
	    if (index2 >=0 ) {
		if (--index3 >= 0) {
		    object h = stage->handler[id][index3];

		    if (h && !h->dead) { // race here
			return;	
		    } else {
			continue;
		    }
		} else {
		    id = mlist[0..index2]*"_";

		    index2--;
		    if (has_index(stage->handler, id)) {
			index3 = sizeof(stage->handler);
			continue;
		    }
		}
	    } else {
		id = UNDEFINED;
		return;
	    }
	}
    }

    mixed index() {
	return id;	
    }

    int(0..1) next() {
	find_next();

	return !!id;
    } 

    mixed value() {
	if (id && index3 > -1) return stage->handlers[id][index3];
	else return UNDEFINED;
    }

    .this_program `+=(int steps) {
	if (steps < 0) error("Cannot move backwards.\n");

	while (steps-- > 0 && id) {
	    find_next(); 
	}

	return this;
    }

    .this_program `+(int steps) {
	if (steps < 0) error("Cannot move backwards.\n");

	.this_program new = .this_program(stage, mlist*"_");
	new->index = index;
	new->id = id;

	new += steps;

	return new;
    }
}

class Stage {
    mapping(string:array(object)) handler = ([]);

    void create() {
    }

    .StageIterator get_iterator(string method) {
	return .StageIterator(this, method);
    }

    void add_handler(object h, string base) {
	if (!handler[base]) {
	    handler[base] = ({ });
	    set_weak_flag(handler[base], Pike.WEAK_VALUES);
	}

	handler[base] += ({ h });
    }
}

mapping(int:object) handler = ([]);
mapping(string:object) stages = ([]);
string start_stage = "start";

int get_new_id() {
    int i;
    while (has_index(handler, i = random(Int.NATIVE_MAX)));

    return i;
}

void set_start_stage(string start_stage) {
    this_program::start_stage = start_stage;
}

void add_stage(string name, object stage) {
    if (stages[name]) error("Sir, I am very sorry, but that seat is already taken.\n");
    stages[name] = stage;
}

int add_method(mapping specs, object child) {
{'fraction_non_alphanumeric': 0.1564625850340136, 'fraction_numerical': 0.00977891156462585, 'mean_word_length': 2.652950310559006, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '653852', 'n_tokens_mistral': 1793, 'n_tokens_neox': 1645, 'n_words': 410}