src.org.python.modules.PyTeeIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
package org.python.modules;
import java.util.Map;
import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyIterator;
import org.python.core.PyNewWrapper;
import org.python.core.PyObject;
import org.python.core.PyType;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
import org.python.util.Generic;
@ExposedType(name = "itertools.tee", base = PyObject.class, isBaseType = false)
public class PyTeeIterator extends PyIterator {
private final int position;
private int count = 0;
private final PyObject iterator;
private final Map buffer;
private final int[] offsets;
PyTeeIterator(PyObject iterator, Map buffer, int[] offsets, int position) {
this.iterator = iterator;
this.buffer = buffer;
this.offsets = offsets;
this.position = position;
}
@ExposedNew
final static PyObject tee___new__ (PyNewWrapper new_, boolean init,
PyType subtype, PyObject[] args, String[] keywords) {
final int nargs = args.length;
// CPython tee ignores keywords, so we do too!
if (nargs < 1 || nargs > 1) {
throw Py.TypeError("tee expected 1 arguments, got " + nargs);
}
return makeTees(args[0], 1)[0];
}
public static PyTeeIterator[] makeTees(PyObject iterable, int n) {
if (n < 0) {
throw Py.ValueError("n must be >= 0");
}
PyObject iterator = iterable.__iter__();
Map buffer = Generic.concurrentMap();
int[] offsets = new int[n];
PyTeeIterator[] tees = new PyTeeIterator[n];
for (int i = 0; i < n; i++) {
offsets[i] = -1;
tees[i] = new PyTeeIterator(iterator, buffer, offsets, i);
}
return tees;
}
protected PyObject nextElement(PyObject pyIter) {
PyObject element = null;
try {
element = pyIter.__iternext__();//next();
} catch (PyException pyEx) {
if (pyEx.match(Py.StopIteration)) {
// store exception - will be used by PyIterator.next()
stopException = pyEx;
} else {
throw pyEx;
}
}
return element;
}
@ExposedMethod
public final PyObject tee_next() {
return next();
}
public PyObject __iternext__() {
final PyObject item;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int j = 0; j < offsets.length; j++) {
if (max < offsets[j]) {
max = offsets[j];
}
if (min > offsets[j]) {
min = offsets[j];
}
}
if (count > max) {
item = nextElement(iterator);
if (item != null) {
buffer.put(count, item);
}
} else if (count < min) {
item = buffer.remove(count);
} else {
item = buffer.get(count);
}
offsets[position] = count;
count++;
return item;
}
}