From: SVN by r. <sv...@ca...> - 2008-01-13 10:54:06
|
Author: roy Date: 2008-01-13 11:42:47 +0100 (Sun, 13 Jan 2008) New Revision: 217 Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java Log: large speed improvement when displaying large result Modified: src/main/java/nl/improved/sqlclient/util/ResultBuilder.java =================================================================== --- src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-13 10:41:19 UTC (rev 216) +++ src/main/java/nl/improved/sqlclient/util/ResultBuilder.java 2008-01-13 10:42:47 UTC (rev 217) @@ -1,10 +1,10 @@ package nl.improved.sqlclient.util; +import java.awt.event.ActionEvent; import java.util.*; public class ResultBuilder { public enum Alignment {LEFT, RIGHT}; - private int columnCount = 0, rowCount = 0; private Map<Integer, Integer> columnSizes = new HashMap<Integer, Integer>(); private List<String> header; @@ -12,16 +12,8 @@ private boolean horizontalSeperatorEnabled = true; private char horizontalSeperator = '-', verticalSeparator ='|'; + private RowList rows = new RowList(); - private Set cellValues = new TreeSet<Cell>(new Comparator<Cell>() { - public int compare(Cell c1, Cell c2) { - if (c1.getRow() != c2.getRow()) { - return c1.getRow() - c2.getRow(); - } - return c1.getColumn() - c2.getColumn(); - } - }); - public void setHorizontalSeparatorEnabled(boolean enabled) { this.horizontalSeperatorEnabled = enabled; } @@ -64,41 +56,21 @@ } public void set(int column,int row, CharSequence s, Alignment alignment) { - columnCount = Math.max(columnCount, column); - rowCount = Math.max(rowCount, row); - Cell c = new Cell(column, row, s, alignment); - if (cellValues.contains(c)) { - cellValues.remove(c); - } - cellValues.add(c); - Integer maxValue = columnSizes.get(new Integer(column)); - if (maxValue == null || maxValue.intValue() < c.getLength()+1) { // +1 because one space at end of column - columnSizes.put(new Integer(column), c.getLength()+1); - } + rows.setValue(column, row, s, alignment); } - private Cell getCell(int col, int row) { - Iterator<Cell> iCellValues = cellValues.iterator(); - while (iCellValues.hasNext()) { - Cell c = iCellValues.next(); - if (c.getRow() == row && c.getColumn() == col) { - return c; - } - } - return null; - } - @Override public String toString() { int rowLength = 2; //add |<row>\n - for (int col = 0; col <= columnCount; col++) { + for (int col = 0; col <= rows.columnCount; col++) { Integer colSize = columnSizes.get(col); if (colSize != null) { rowLength += colSize.intValue() + 1; // add | } } - StringBuilder result = new StringBuilder((rowLength * (rowCount + 2 + (header == null ? 0 : 1))) + (footer == null ? 0 : footer.length()+1)); + int probableLength = (rowLength * (rows.rowCount + 2 + (header == null ? 0 : 1))) + (footer == null ? 0 : footer.length()+1) + 500; + StringBuilder result = new StringBuilder(probableLength); if (header != null) { if (horizontalSeperatorEnabled) { for (int i = 0; i < rowLength-1; i++) { @@ -126,21 +98,27 @@ } } result.append('\n'); - for (int row = 0; row <= rowCount; row++) { - result.append(verticalSeparator); - for (int col = 0; col <= columnCount; col++) { - Cell c = getCell(col, row); - int colStart = result.length(); - int spaceUsed = 0; - if (c != null) { - result.append(c.getValue()); - spaceUsed = c.getLength(); - } - Integer colSize = columnSizes.get(col); + Iterator<Cell> cells = rows.iterator(); + int prevRow = 0; + result.append(verticalSeparator); + while (cells.hasNext()) { + Cell cell = cells.next(); + if (cell != null && cell.row != prevRow) { + result.append('\n'); + result.append('|'); + prevRow = cell.row; + } + int colStart = result.length(); + int spaceUsed = 0; + if (cell != null) { + result.append(cell.getValue()); + spaceUsed = cell.getLength(); + + Integer colSize = columnSizes.get(cell.col); if (colSize != null) { int colSizeInt = colSize.intValue(); for (int i = spaceUsed; i < colSizeInt; i++) { - if (c == null || c.getAlignment() == Alignment.LEFT) { + if (cell == null || cell.getAlignment() == Alignment.LEFT) { result.append(' '); } else { result.insert(colStart, ' '); @@ -149,8 +127,8 @@ result.append(verticalSeparator); } } - result.append('\n'); } + result.append('\n'); if (horizontalSeperatorEnabled) { for (int i = 0; i < rowLength-1; i++) { result.append(horizontalSeperator); @@ -165,7 +143,6 @@ } private static class Cell { - private int row, col; private CharSequence buffer; private Alignment alignment; @@ -210,12 +187,122 @@ } } + private class RowList { + private int columnCount = 0, rowCount = 0; + + private Row firstRow = null; + private Row lastRow = null; + + public RowList() { + } + + public void setValue(int col, int row, CharSequence value, Alignment align) { + // TODO remove first row(s) when rowsize larger then maxsize + columnCount = Math.max(columnCount, col); + rowCount = Math.max(rowCount, row); + Row newRow; + if (firstRow == null) { + firstRow = new Row(row); + lastRow = firstRow; + newRow = firstRow; + } else if (lastRow.rowNum == row) { + newRow = lastRow; + } else if (lastRow.rowNum < row) { + lastRow.nextRow = new Row(row); + newRow = lastRow.nextRow; + lastRow = newRow; + } else { + throw new IllegalStateException("Please add rows in order!"); + } + + Cell c = new Cell(col, row, value, align); + if (newRow.cells.contains(c)) { + newRow.cells.remove(c); + } + newRow.cells.add(c); + Integer maxValue = columnSizes.get(new Integer(col)); + if (maxValue == null || maxValue.intValue() < c.getLength()+1) { // +1 because one space at end of column + columnSizes.put(new Integer(col), c.getLength()+1); + } + } + + public Iterator<Cell> iterator() { + Iterator<Cell> i = new Iterator<Cell>() { + Row curRow = firstRow; + int colNr = 0; + @Override + public boolean hasNext() { + return (colNr <= columnCount) || curRow.nextRow != null; + } + + @Override + public Cell next() { + if (colNr > columnCount) { + colNr = 0; + curRow = curRow.nextRow; + } + return curRow.getCell(colNr++); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Not supported."); + } + }; + return i; + } + + private class Row { + public Row nextRow; + public int rowNum; + public List<Cell> cells; + + public Row(int rowNum) { + this.rowNum = rowNum; + cells = new ArrayList<Cell>(); + } + + Cell getCell(int col) { + Cell c; + if (cells.size() > col) { + c = cells.get(col); + if (c.col == col) { + return c; + } + } + Iterator<Cell> iCells = cells.iterator(); + while (iCells.hasNext()) { + c = iCells.next(); + if (c.col == col) { + return c; + } + } + return null; + } + } + } + public static void main(String[] args) throws Exception { ResultBuilder builder = new ResultBuilder(); - builder.set(0,0, "cell 0,0"); - builder.set(1,0, "cell 1,0 and even more stuff"); - builder.set(0,1, "cell 0,1 and some other stuff"); - builder.set(1,1, "cell 1,1"); + builder.set(0, 0, "faaaaaa"); + builder.set(1, 0, "fbbbbbb"); + builder.set(2, 0, "fcccccc"); + builder.set(3, 0, "fdddddd"); + builder.set(4, 0, "feeeeee"); + for (int row = 1; row < 2000; row++) { + builder.set(0, row, "aaaaaaa"); + builder.set(1, row, "bbbbbbb"); + builder.set(2, row, "ccccccc"); + builder.set(3, row, "ddddddd"); + builder.set(4, row, "eeeeeee"); + } + builder.set(0, 2000, "laaaaaa"); + builder.set(1, 2000, "lbbbbbb"); + builder.set(2, 2000, "lcccccc"); + builder.set(3, 2000, "ldddddd"); + builder.set(4, 2000, "leeeeee"); + long start = System.currentTimeMillis(); System.out.println(builder.toString()); + System.out.println("TIME: "+ (System.currentTimeMillis() - start)); } } |