diff --git a/python/helpers/pydev/pydev_console_utils.py b/python/helpers/pydev/pydev_console_utils.py index 043351587155..2ba020a0c585 100644 --- a/python/helpers/pydev/pydev_console_utils.py +++ b/python/helpers/pydev/pydev_console_utils.py @@ -390,11 +390,13 @@ class BaseInterpreterInterface: name = attr.split("\t")[-1] array = pydevd_vars.evalInContext(name, self.getNamespace(), self.getNamespace()) + metaxml, r, c, f = pydevd_vars.array_to_meta_xml(array, name, format) + xml += metaxml + format = '%' + f if rows == -1 and cols == -1: - xml += pydevd_vars.array_to_meta_xml(array, name, format) - else: - xml += pydevd_vars.array_to_xml(array, roffset, coffset, rows, cols, format) - + rows = r + cols = c + xml += pydevd_vars.array_to_xml(array, roffset, coffset, rows, cols, format) xml += "" return xml diff --git a/python/helpers/pydev/pydevd_comm.py b/python/helpers/pydev/pydevd_comm.py index 8f5fea6f0fb2..7d55d46bc0d3 100644 --- a/python/helpers/pydev/pydevd_comm.py +++ b/python/helpers/pydev/pydevd_comm.py @@ -991,11 +991,13 @@ class InternalGetArray(InternalThreadCommand): xml = "" - # need metadata + metaxml, rows, cols, format = pydevd_vars.array_to_meta_xml(var, self.name, self.format) + xml += metaxml + self.format = '%' + format if self.rows == -1 and self.cols == -1: - xml += pydevd_vars.array_to_meta_xml(var, self.name, self.format) - else: - xml += pydevd_vars.array_to_xml(var, self.roffset, self.coffset, self.rows, self.cols, self.format) + self.rows = rows + self.cols = cols + xml += pydevd_vars.array_to_xml(var, self.roffset, self.coffset, self.rows, self.cols, self.format) xml += "" cmd = dbg.cmdFactory.makeGetArrayMessage(self.sequence, xml) dbg.writer.addCommand(cmd) diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py index b03560345844..eebe6f3d1c01 100644 --- a/python/helpers/pydev/pydevd_vars.py +++ b/python/helpers/pydev/pydevd_vars.py @@ -414,7 +414,7 @@ def array_to_xml(array, roffset, coffset, rows, cols, format): array = array[roffset:] rows = min(rows, len(array)) - xml += "" % (False, rows, cols) + xml += "" % (rows, cols) for row in range(rows): xml += "" % to_string(row) for col in range(cols): @@ -491,9 +491,9 @@ def array_to_meta_xml(array, name, format): bounds = (0, 0) if type in "biufc": bounds = (array.min(), array.max()) - xml = '' % \ - (True, slice, rows, cols, format, type, bounds[1], bounds[0]) - return xml + xml = '' % \ + (slice, rows, cols, format, type, bounds[1], bounds[0]) + return xml, rows, cols, format diff --git a/python/pydevSrc/com/jetbrains/python/debugger/ArrayChunk.java b/python/pydevSrc/com/jetbrains/python/debugger/ArrayChunk.java index d7e5ade2895a..b17fbb25b292 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/ArrayChunk.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/ArrayChunk.java @@ -88,16 +88,4 @@ public class ArrayChunk { public Object[][] getData() { return myData; } - - public boolean metaOnly() { - return myData == null; - } - - public boolean containsMeta() { - return !mySlicePresentation.isEmpty() && - myRows > 0 && - myColumns > 0 && - !myFormat.isEmpty() && - !myType.isEmpty(); - } } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java index 42f17bd042f0..198009bbcc09 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProtocolParser.java @@ -181,34 +181,42 @@ public class ProtocolParser { public static ArrayChunk parseArrayValues(final String text, final PyFrameAccessor frameAccessor) throws PyDebuggerException { final XppReader reader = openReader(text, false); - int cols = 0; - int rows = 0; - + ArrayChunk result = null; if (reader.hasMoreChildren()) { reader.moveDown(); if (!"array".equals(reader.getNodeName())) { throw new PyDebuggerException("Expected at first node, found " + reader.getNodeName()); } - boolean meta = readString(reader, "meta", null).equals("True"); - if (meta) { - String slice = readString(reader, "slice", null); - rows = readInt(reader, "rows", null); - cols = readInt(reader, "cols", null); - String format = "%" + readString(reader, "format", null); - String type = readString(reader, "type", null); - String max = readString(reader, "max", null); - String min = readString(reader, "min", null); - return new ArrayChunk(new PyDebugValue(slice, null, null, false, false, frameAccessor), slice, rows, cols, max, min, format, type, null); + String slice = readString(reader, "slice", null); + int rows = readInt(reader, "rows", null); + int cols = readInt(reader, "cols", null); + String format = "%" + readString(reader, "format", null); + String type = readString(reader, "type", null); + String max = readString(reader, "max", null); + String min = readString(reader, "min", null); + result = + new ArrayChunk(new PyDebugValue(slice, null, null, false, false, frameAccessor), slice, rows, cols, max, min, format, type, null); + reader.moveUp(); + } + + Object[][] data = parseArrayValues(reader, frameAccessor); + return new ArrayChunk(result.getValue(), result.getSlicePresentation(), result.getRows(), result.getColumns(), result.getMax(), + result.getMin(), result.getFormat(), result.getType(), data); + } + + public static Object[][] parseArrayValues(final XppReader reader, final PyFrameAccessor frameAccessor) throws PyDebuggerException { + int rows = -1; + int cols = -1; + if (reader.hasMoreChildren()) { + reader.moveDown(); + if (!"arraydata".equals(reader.getNodeName())) { + throw new PyDebuggerException("Expected at second node, found " + reader.getNodeName()); } rows = readInt(reader, "rows", null); cols = readInt(reader, "cols", null); reader.moveUp(); } - return parseArrayValues(reader, frameAccessor, cols, rows); - } - - public static ArrayChunk parseArrayValues(final XppReader reader, final PyFrameAccessor frameAccessor, final int cols, final int rows) throws PyDebuggerException { if (rows <= 0 || cols <= 0) { throw new PyDebuggerException("Array xml: bad rows or columns number: (" + rows + ", " + cols + ")"); } @@ -231,15 +239,16 @@ public class ProtocolParser { } currRow += 1; currCol = 0; - } else { + } + else { PyDebugValue value = parseValue(reader, frameAccessor); - values[currRow-1][currCol] = value.getValue(); + values[currRow - 1][currCol] = value.getValue(); currCol += 1; } reader.moveUp(); } - return new ArrayChunk(new PyDebugValue("", null, null, false, false, frameAccessor), "", rows, cols, null, null, null, null, values); + return values; } private static XppReader openReader(final String text, final boolean checkForContent) throws PyDebuggerException { diff --git a/python/src/com/jetbrains/python/debugger/array/AsyncArrayTableModel.java b/python/src/com/jetbrains/python/debugger/array/AsyncArrayTableModel.java index c25ef27b6b17..d57274c2e9e7 100644 --- a/python/src/com/jetbrains/python/debugger/array/AsyncArrayTableModel.java +++ b/python/src/com/jetbrains/python/debugger/array/AsyncArrayTableModel.java @@ -26,6 +26,8 @@ import com.jetbrains.python.debugger.ArrayChunk; import com.jetbrains.python.debugger.PyDebugValue; import javax.swing.table.AbstractTableModel; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.*; /** @@ -165,7 +167,51 @@ public class AsyncArrayTableModel extends AbstractTableModel { } } - public void addToCache(ArrayChunk chunk) { - //TODO: add preloaded values + public void addToCache(final ArrayChunk chunk) { + Object[][] data = chunk.getData(); + int cols = data.length; + int rows = data[0].length; + for (int roffset = 0; roffset < rows / CHUNK_ROW_SIZE; roffset++) { + for (int coffset = 0; coffset < cols / CHUNK_COL_SIZE; coffset++) { + Pair key = itemToChunkKey(roffset * CHUNK_ROW_SIZE, coffset * CHUNK_COL_SIZE); + final Object[][] chunkData = new Object[CHUNK_ROW_SIZE][CHUNK_COL_SIZE]; + for (int r = 0; r < CHUNK_ROW_SIZE; r++) { + for (int c = 0; c < CHUNK_COL_SIZE; c++) { + chunkData[r][c] = data[roffset + r][coffset + c]; + } + } + myChunkCache.put(key, new ListenableFuture() { + @Override + public void addListener(Runnable listener, Executor executor) { + + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public ArrayChunk get() throws InterruptedException, ExecutionException { + return new ArrayChunk(chunk.getValue(), null, 0, 0, null, null, null, null, chunkData); + } + + @Override + public ArrayChunk get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return new ArrayChunk(chunk.getValue(), null, 0, 0, null, null, null, null, chunkData); + } + }); + } + } } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java b/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java index bab68147db79..950434855bd5 100644 --- a/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java +++ b/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java @@ -174,9 +174,6 @@ public class NumpyArrayTable { initComponent(); ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { - - final ExecutorService myExecutorService = Executors.newSingleThreadExecutor(); - @Override public void run() { final PyDebugValue value = getDebugValue(); @@ -187,35 +184,18 @@ public class NumpyArrayTable { final String format = getFormat().isEmpty() ? "%" : getFormat(); - final ListenableFutureTask task = ListenableFutureTask.create(new Callable() { - @Override - public ArrayChunk call() throws Exception { - return value.getFrameAccessor() - .getArrayItems(slicedValue, 0, 0, -1, -1, format); - } - }); - - task.addListener(new Runnable() { - @Override - public void run() { - if (task.isDone()) { - try { - initUi(task.get(), inPlace); - } - catch (Exception e) { - showError(e.getMessage()); - } - } - } - }, myExecutorService); - - myExecutorService.execute(task); + try { + initUi(value.getFrameAccessor() + .getArrayItems(slicedValue, 0, 0, -1, -1, format), inPlace); + } + catch (PyDebuggerException e) { + showError(e.getMessage()); + } } }); } private void initUi(@NotNull final ArrayChunk chunk, final boolean inPlace) { - if (chunk.containsMeta()) { myPagingModel = new AsyncArrayTableModel(Math.min(chunk.getRows(), ROWS_IN_DEFAULT_VIEW), Math.min(chunk.getColumns(), COLUMNS_IN_DEFAULT_VIEW), this); myPagingModel.addToCache(chunk); @@ -249,10 +229,6 @@ public class NumpyArrayTable { } } }); - } - else { - showError("Bad metadata for array " + chunk.getValue()); - } } private static String getTitlePresentation(String slice) {