bug 58670: replace SXSSFRow's storage of SXSSFCells[] with a TreeMap<Int, SXSSFCell>

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1717192 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2015-11-30 06:07:49 +00:00
parent b5ad3a9327
commit 8410c84ad6

View File

@ -18,7 +18,10 @@
package org.apache.poi.xssf.streaming; package org.apache.poi.xssf.streaming;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
@ -35,8 +38,7 @@ import org.apache.poi.util.Internal;
public class SXSSFRow implements Row, Comparable<SXSSFRow> public class SXSSFRow implements Row, Comparable<SXSSFRow>
{ {
private final SXSSFSheet _sheet; private final SXSSFSheet _sheet;
private SXSSFCell[] _cells; private final SortedMap<Integer, SXSSFCell> _cells = new TreeMap<Integer, SXSSFCell>();
private int _maxColumn=-1;
private short _style=-1; private short _style=-1;
private short _height=-1; private short _height=-1;
private boolean _zHeight = false; private boolean _zHeight = false;
@ -45,11 +47,25 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
private Boolean _hidden; private Boolean _hidden;
private Boolean _collapsed; private Boolean _collapsed;
/**
*
* @param sheet the parent sheet the row belongs to
* @param initialSize - no longer needed
* @deprecated 2015-11-30 (circa POI 3.14beta1). Use {@link #SXSSFRow(SXSSFSheet)} instead.
*/
public SXSSFRow(SXSSFSheet sheet, int initialSize) public SXSSFRow(SXSSFSheet sheet, int initialSize)
{ {
_sheet=sheet; this(sheet);
_cells=new SXSSFCell[initialSize];
} }
public SXSSFRow(SXSSFSheet sheet)
{
_sheet=sheet;
}
/**
* @deprecated 3.14beta1 (circa 2015-11-30). Use {@link #cellIterator} instead.
*/
public Iterator<Cell> allCellsIterator() public Iterator<Cell> allCellsIterator()
{ {
return new CellIterator(); return new CellIterator();
@ -59,7 +75,6 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
return _height!=-1; return _height!=-1;
} }
@Override
public int getOutlineLevel(){ public int getOutlineLevel(){
return _outlineLevel; return _outlineLevel;
} }
@ -93,6 +108,9 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
this._collapsed = collapsed; this._collapsed = collapsed;
} }
//begin of interface implementation //begin of interface implementation
/**
* {@inheritDoc}
*/
@Override @Override
public Iterator<Cell> iterator() public Iterator<Cell> iterator()
{ {
@ -113,7 +131,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override @Override
public SXSSFCell createCell(int column) public SXSSFCell createCell(int column)
{ {
return createCell(column,Cell.CELL_TYPE_BLANK); return createCell(column, Cell.CELL_TYPE_BLANK);
} }
/** /**
@ -131,16 +149,9 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
public SXSSFCell createCell(int column, int type) public SXSSFCell createCell(int column, int type)
{ {
checkBounds(column); checkBounds(column);
SXSSFCell cell = new SXSSFCell(this, type);
if(column>=_cells.length) _cells.put(column, cell);
{ return cell;
SXSSFCell[] newCells=new SXSSFCell[Math.max(column+1,_cells.length*2)];
System.arraycopy(_cells,0,newCells,0,_cells.length);
_cells=newCells;
}
_cells[column]=new SXSSFCell(this,type);
if(column>_maxColumn) _maxColumn=column;
return _cells[column];
} }
/** /**
@ -164,19 +175,23 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override @Override
public void removeCell(Cell cell) public void removeCell(Cell cell)
{ {
int index=getCellIndex(cell); int index = getCellIndex((SXSSFCell) cell);
if(index>=0) _cells.remove(index);
{
_cells[index]=null;
while(_maxColumn>=0&&_cells[_maxColumn]==null) _maxColumn--;
}
} }
int getCellIndex(Cell cell) /**
* Return the column number of a cell if it is in this row
* Otherwise return -1
*
* @param cell the cell to get the index of
* @return cell column index if it is in this row, -1 otherwise
*/
/*package*/ int getCellIndex(SXSSFCell cell)
{ {
for(int i=0;i<=_maxColumn;i++) for (Entry<Integer, SXSSFCell> entry : _cells.entrySet()) {
{ if (entry.getValue()==cell) {
if(_cells[i]==cell) return i; return entry.getKey();
}
} }
return -1; return -1;
} }
@ -205,37 +220,19 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
} }
/** /**
* Get the cell representing a given column (logical cell) 0-based. If you * Get the cell representing a given column (logical cell) 0-based.
* ask for a cell that is not defined....you get a null. * If cell is missing or blank, uses the workbook's MissingCellPolicy
* to determine the return value.
* *
* @param cellnum 0 based column number * @param cellnum 0 based column number
* @return Cell representing that column or null if undefined. * @return Cell representing that column or null if undefined.
* @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy) * @see #getCell(int, org.apache.poi.ss.usermodel.Row.MissingCellPolicy)
* @throws RuntimeException if cellnum is out of bounds
*/ */
@Override @Override
public SXSSFCell getCell(int cellnum) { public SXSSFCell getCell(int cellnum) {
if(cellnum < 0) throw new IllegalArgumentException("Cell index must be >= 0");
SXSSFCell cell = cellnum > _maxColumn ? null : _cells[cellnum];
MissingCellPolicy policy = _sheet.getWorkbook().getMissingCellPolicy(); MissingCellPolicy policy = _sheet.getWorkbook().getMissingCellPolicy();
if(policy == RETURN_NULL_AND_BLANK) { return getCell(cellnum, policy);
return cell;
}
if (policy == RETURN_BLANK_AS_NULL) {
if (cell == null) return cell;
if (cell.getCellType() == Cell.CELL_TYPE_BLANK) {
return null;
}
return cell;
}
if (policy == CREATE_NULL_AS_BLANK) {
if (cell == null) {
return createCell((short) cellnum, Cell.CELL_TYPE_BLANK);
}
return cell;
}
throw new IllegalArgumentException("Illegal policy " + policy + " (" + policy.id + ")");
} }
/** /**
@ -248,25 +245,27 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
* @see Row#CREATE_NULL_AS_BLANK * @see Row#CREATE_NULL_AS_BLANK
*/ */
@Override @Override
public Cell getCell(int cellnum, MissingCellPolicy policy) public SXSSFCell getCell(int cellnum, MissingCellPolicy policy)
{ {
Cell cell = getCell(cellnum); checkBounds(cellnum);
if(policy == RETURN_NULL_AND_BLANK)
// FIXME: replace with switch(enum)
final SXSSFCell cell = _cells.get(cellnum);
if (policy == RETURN_NULL_AND_BLANK)
{ {
return cell; return cell;
} }
if(policy == RETURN_BLANK_AS_NULL) else if (policy == RETURN_BLANK_AS_NULL)
{ {
if(cell == null) return cell; if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK)
if(cell.getCellType() == Cell.CELL_TYPE_BLANK)
{ {
return null; return null;
} }
return cell; return cell;
} }
if(policy == CREATE_NULL_AS_BLANK) else if (policy == CREATE_NULL_AS_BLANK)
{ {
if(cell == null) if (cell == null)
{ {
return createCell(cellnum, Cell.CELL_TYPE_BLANK); return createCell(cellnum, Cell.CELL_TYPE_BLANK);
} }
@ -284,9 +283,11 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override @Override
public short getFirstCellNum() public short getFirstCellNum()
{ {
for(int i=0;i<=_maxColumn;i++) try {
if(_cells[i]!=null) return (short)i; return _cells.firstKey().shortValue();
return -1; } catch (final NoSuchElementException e) {
return -1;
}
} }
/** /**
@ -311,7 +312,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override @Override
public short getLastCellNum() public short getLastCellNum()
{ {
return _maxColumn == -1 ? -1 : (short)(_maxColumn+1); return _cells.isEmpty() ? -1 : (short)(_cells.lastKey() + 1);
} }
/** /**
@ -323,12 +324,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override @Override
public int getPhysicalNumberOfCells() public int getPhysicalNumberOfCells()
{ {
int count=0; return _cells.size();
for(int i=0;i<=_maxColumn;i++)
{
if(_cells[i]!=null) count++;
}
return count;
} }
/** /**
@ -445,8 +441,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
} }
/** /**
* @return Cell iterator of the physically defined cells. Note element 4 may * {@inheritDoc}
* actually be row cell depending on how many are defined!
*/ */
@Override @Override
public Iterator<Cell> cellIterator() public Iterator<Cell> cellIterator()
@ -473,8 +468,9 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
int pos=0; int pos=0;
FilledCellIterator(){ FilledCellIterator(){
for (int i = 0; i <= _maxColumn; i++) { int maxColumn = getLastCellNum(); //last column PLUS ONE
if (_cells[i] != null) { for (int i = 0; i < maxColumn; i++) {
if (_cells.get(i) != null) {
pos = i; pos = i;
break; break;
} }
@ -483,18 +479,22 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
public boolean hasNext() public boolean hasNext()
{ {
return pos <= _maxColumn; int maxColumn = getLastCellNum(); //last column PLUS ONE
return pos < maxColumn;
} }
void advanceToNext() void advanceToNext()
{ {
pos++; int maxColumn = getLastCellNum(); //last column PLUS ONE
while(pos<=_maxColumn&&_cells[pos]==null) pos++; do {
pos++;
}
while (pos<maxColumn && _cells.get(pos)==null);
} }
public Cell next() throws NoSuchElementException public Cell next() throws NoSuchElementException
{ {
if (hasNext()) if (hasNext())
{ {
Cell retval=_cells[pos]; Cell retval=_cells.get(pos);
advanceToNext(); advanceToNext();
return retval; return retval;
} }
@ -514,12 +514,13 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
int pos=0; int pos=0;
public boolean hasNext() public boolean hasNext()
{ {
return pos <= _maxColumn; int maxColumn = getLastCellNum(); //last column PLUS ONE
return pos < maxColumn;
} }
public Cell next() throws NoSuchElementException public Cell next() throws NoSuchElementException
{ {
if (hasNext()) if (hasNext())
return _cells[pos++]; return _cells.get(pos++);
else else
throw new NoSuchElementException(); throw new NoSuchElementException();
} }