<commit_before>load("util.js");

var io = {
	print: function(s) {
		return print(s);
	},
	quit: function() {
		return quit();
	},
};

var connector = {
	selector: java.nio.channels.Selector.open(),
	read_buf: java.nio.ByteBuffer.allocate(1024),
	events: [],

	/* Register/unregister descriptors and operations with the selector.
	   These assume that only one ops of each type is registered per
	   descriptor; for example, you can't register two read events, because
	   when one is unregistered it will unregister the other. */
	register: function(sd, ops) {
		var key = sd.keyFor(this.selector);
		var current_ops = 0;
		if (key)
			current_ops = key.interestOps();
		return sd.register(this.selector, current_ops | ops);
	},
	unregister: function(sd, ops) {
		var key = sd.keyFor(this.selector);
		var current_ops = 0;
		if (key)
			current_ops = key.interestOps();
		return sd.register(this.selector, current_ops & ~ops);
	},

	bytebuffer_to_string: function(bb) {
		return String(new java.lang.String(java.util.Arrays.copyOf(bb.array(), bb.position()), "ISO-8859-1"));
	},
	string_to_bytebuffer: function(s) {
		return java.nio.ByteBuffer.wrap(new java.lang.String(s).getBytes("ISO-8859-1"));
	},

	/* Stringify/serialize a socket descriptor. */
	s_sd: function(sd) {
		var s = sd.socket();
		return s["class"] + "\0" + s.getInetAddress().getHostAddress() + "\0" + s.getPort();
	},

	handle_selection_key: function(key) {
		var channel = key.channel();
		if ((key.readyOps() & java.nio.channels.SelectionKey.OP_ACCEPT)
			== java.nio.channels.SelectionKey.OP_ACCEPT) {
			this.op_accept(channel);
		} else if ((key.readyOps() & java.nio.channels.SelectionKey.OP_CONNECT)
			== java.nio.channels.SelectionKey.OP_CONNECT) {
			this.op_connect(channel);
		} else if ((key.readyOps() & java.nio.channels.SelectionKey.OP_READ)
			== java.nio.channels.SelectionKey.OP_READ) {
			this.op_read(channel);
		} else if ((key.readyOps() & java.nio.channels.SelectionKey.OP_WRITE)
			== java.nio.channels.SelectionKey.OP_WRITE) {
			this.op_write(channel);
		} else {
			throw new Error("Unknown selection key op.");
		}
	},
	op_accept: function(channel) {
		var c = channel.socket().accept();
		this.events.push({
			type: "accept",
			sd: channel,
			address: c.getInetAddress().getHostAddress(),
			port: c.getPort(),
			client: c.channel,
		});
		/* For accept only, do not unregister the selection key. */
	},
	op_connect: function(channel) {
		if (channel.isConnectionPending())
			channel.finishConnect();
		this.events.push({
			type: "connect",
			sd: channel,
			address: channel.socket().getInetAddress().getHostAddress(),
			port: channel.socket().getPort(),
		});
		this.unregister(channel, java.nio.channels.SelectionKey.OP_CONNECT);
	},
	op_read: function(channel) {
		this.read_buf.clear();
		var n = channel.read(this.read_buf);
		var data;
		if (n == -1)
			data = undefined;
		else
			data = this.bytebuffer_to_string(this.read_buf);
		this.events.push({
			type: "recv",
			sd: channel,
			data: data,
		});
		this.unregister(channel, java.nio.channels.SelectionKey.OP_READ);
	},
	op_write: function(channel) {
		this.events.push({
			type: "send",
			sd: channel,
		});
		this.unregister(channel, java.nio.channels.SelectionKey.OP_WRITE);
	},

	wait_for_event: function() {
		while (true) {
			if (this.events.length > 0)
				return this.events.shift();
<commit_msg>Move unregistration out of op handlers.<commit_after>load("util.js");

var io = {
	print: function(s) {
		return print(s);
	},
	quit: function() {
		return quit();
	},
};

var connector = {
	selector: java.nio.channels.Selector.open(),
	read_buf: java.nio.ByteBuffer.allocate(1024),
	events: [],

	/* Register/unregister descriptors and operations with the selector.
	   These assume that only one ops of each type is registered per
	   descriptor; for example, you can't register two read events, because
	   when one is unregistered it will unregister the other. */
	register: function(sd, ops) {
		var key = sd.keyFor(this.selector);
		var current_ops = 0;
		if (key)
			current_ops = key.interestOps();
		return sd.register(this.selector, current_ops | ops);
	},
	unregister: function(sd, ops) {
		var key = sd.keyFor(this.selector);
		var current_ops = 0;
		if (key)
			current_ops = key.interestOps();
		return sd.register(this.selector, current_ops & ~ops);
	},

	bytebuffer_to_string: function(bb) {
		return String(new java.lang.String(java.util.Arrays.copyOf(bb.array(), bb.position()), "ISO-8859-1"));
	},
	string_to_bytebuffer: function(s) {
		return java.nio.ByteBuffer.wrap(new java.lang.String(s).getBytes("ISO-8859-1"));
	},

	/* Stringify/serialize a socket descriptor. */
	s_sd: function(sd) {
		var s = sd.socket();
		return s["class"] + "\0" + s.getInetAddress().getHostAddress() + "\0" + s.getPort();
	},

	handle_selection_key: function(key) {
		var channel = key.channel();
		if ((key.readyOps() & java.nio.channels.SelectionKey.OP_ACCEPT)
			== java.nio.channels.SelectionKey.OP_ACCEPT) {
			this.op_accept(channel);
			/* For accept only, do not unregister the selection key. */
		} else if ((key.readyOps() & java.nio.channels.SelectionKey.OP_CONNECT)
			== java.nio.channels.SelectionKey.OP_CONNECT) {
			this.op_connect(channel);
			this.unregister(channel, java.nio.channels.SelectionKey.OP_CONNECT);
		} else if ((key.readyOps() & java.nio.channels.SelectionKey.OP_READ)
			== java.nio.channels.SelectionKey.OP_READ) {
			this.op_read(channel);
			this.unregister(channel, java.nio.channels.SelectionKey.OP_READ);
		} else if ((key.readyOps() & java.nio.channels.SelectionKey.OP_WRITE)
			== java.nio.channels.SelectionKey.OP_WRITE) {
			this.op_write(channel);
			this.unregister(channel, java.nio.channels.SelectionKey.OP_WRITE);
		} else {
			throw new Error("Unknown selection key op.");
		}
	},
	op_accept: function(channel) {
		var c = channel.socket().accept();
		this.events.push({
			type: "accept",
			sd: channel,
			address: c.getInetAddress().getHostAddress(),
			port: c.getPort(),
			client: c.channel,
		});
	},
	op_connect: function(channel) {
		if (channel.isConnectionPending())
			channel.finishConnect();
		this.events.push({
			type: "connect",
			sd: channel,
			address: channel.socket().getInetAddress().getHostAddress(),
			port: channel.socket().getPort(),
		});
	},
	op_read: function(channel) {
		this.read_buf.clear();
		var n = channel.read(this.read_buf);
		var data;
		if (n == -1)
			data = undefined;
		else
			data = this.bytebuffer_to_string(this.read_buf);
		this.events.push({
			type: "recv",
			sd: channel,
			data: data,
		});
	},
	op_write: function(channel) {
		this.events.push({
			type: "send",
			sd: channel,
		});
	},

	wait_for_event: function() {
		while (true) {
			if (this.events.length > 0)
				return this.events.shift();

{'fraction_non_alphanumeric': 0.15802650957290132, 'fraction_numerical': 0.005891016200294551, 'mean_word_length': 3.9533187454412837, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '3411932', 'n_tokens_mistral': 2573, 'n_tokens_neox': 2328, 'n_words': 477}