diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2018-05-22 02:09:04 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2018-05-22 02:09:04 +0000 |
commit | f5659151a36e02a82b6b52795cb9788ad2c74a4d (patch) | |
tree | 9a54f9e8ed228fe53382de1e082ef3cfbe569e0d | |
parent | bfc70bd6186b841856e697ce8d8ade577c1b75c8 (diff) | |
download | jackcess-f5659151a36e02a82b6b52795cb9788ad2c74a4d.tar.gz jackcess-f5659151a36e02a82b6b52795cb9788ad2c74a4d.zip |
Create new usage map correctly when adding an index to an existing table. fixes #147
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1152 f203690c-595d-4dc9-a70b-905162fa7fd2
-rw-r--r-- | src/changes/changes.xml | 12 | ||||
-rw-r--r-- | src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java | 476 |
2 files changed, 249 insertions, 239 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml index c954674..13ed1c9 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -8,6 +8,10 @@ <action dev="jahlborn" type="update"> Add some additional property keys and relevant enums for values. </action> + <action dev="jahlborn" type="fix" system="SourceForge2" issue="147"> + Create new usage map correctly when adding an index to an existing + table. + </action> </release> <release version="2.1.11" date="2018-03-04"> <action dev="jahlborn" type="fix" system="SourceForge2" issue="145"> @@ -149,7 +153,7 @@ system property), per-database, and per-table. </action> </release> - <release version="2.1.0" date="2015-04-16" + <release version="2.1.0" date="2015-04-16" description="Relicense to Apache License"> <action dev="jahlborn" type="add"> OpenHMS relicenses to Apache License, 2.0! @@ -269,7 +273,7 @@ <action dev="jahlborn" type="fix"> Make reading long value columns more lenient (MEMO/OLE). </action> - <action dev="jahlborn" type="add" system="SourceForge2Features" + <action dev="jahlborn" type="add" system="SourceForge2Features" issue="16"> Add support for modifying PropertyMaps. </action> @@ -289,7 +293,7 @@ <action dev="jahlborn" type="fix"> Make reading long value columns more lenient (MEMO/OLE). </action> - </release> + </release> <release version="1.2.14.2" date="2013-08-25"> <action dev="jahlborn" type="fix" system="SourceForge2" issue="96"> Fix reading of Properties with multiple value blocks. @@ -816,7 +820,7 @@ characters (and other situations where tables could not be opened in Access). Remove hack which forced every table name to have uppercase first character. - </action> + </action> <action dev="jahlborn" type="update"> Clean up compressed text handling. </action> diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java index aa824df..74c27f5 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/TableImpl.java @@ -57,18 +57,18 @@ import org.apache.commons.logging.LogFactory; * A single database table * <p> * Is not thread-safe. - * + * * @author Tim McCune * @usage _intermediate_class_ */ public class TableImpl implements Table -{ +{ private static final Log LOG = LogFactory.getLog(TableImpl.class); private static final short OFFSET_MASK = (short)0x1FFF; private static final short DELETED_ROW_MASK = (short)0x8000; - + private static final short OVERFLOW_ROW_MASK = (short)0x4000; static final int MAGIC_TABLE_NUMBER = 1625; @@ -182,13 +182,13 @@ public class TableImpl implements Table /** default cursor for iterating through the table, kept here for basic table traversal */ private CursorImpl _defaultCursor; - + /** * Only used by unit tests * @usage _advanced_method_ */ - protected TableImpl(boolean testing, List<ColumnImpl> columns) - throws IOException + protected TableImpl(boolean testing, List<ColumnImpl> columns) + throws IOException { if(!testing) { throw new IllegalArgumentException(); @@ -215,7 +215,7 @@ public class TableImpl implements Table _ownedPages = null; _freeSpacePages = null; } - + /** * @param database database which owns this table * @param tableBuffer Buffer to read the table with @@ -251,17 +251,17 @@ public class TableImpl implements Table _ownedPages = UsageMap.read(getDatabase(), tableBuffer); tableBuffer.position(getFormat().OFFSET_FREE_SPACE_PAGES); _freeSpacePages = UsageMap.read(getDatabase(), tableBuffer); - + for (int i = 0; i < _indexCount; i++) { _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat())); } - + readColumnDefinitions(tableBuffer, columnCount); readIndexDefinitions(tableBuffer); // read column usage map info - while((tableBuffer.remaining() >= 2) && + while((tableBuffer.remaining() >= 2) && readColumnUsageMaps(tableBuffer)) { // keep reading ... } @@ -306,15 +306,15 @@ public class TableImpl implements Table public int getMaxColumnCount() { return _maxColumnCount; } - + public int getColumnCount() { return _columns.size(); } - + public DatabaseImpl getDatabase() { return _database; } - + /** * @usage _advanced_method_ */ @@ -336,7 +336,7 @@ public class TableImpl implements Table public void setErrorHandler(ErrorHandler newErrorHandler) { _tableErrorHandler = newErrorHandler; - } + } public int getTableDefPageNumber() { return _tableDefPageNumber; @@ -395,7 +395,7 @@ public class TableImpl implements Table return count; } - + protected TempPageHolder getLongValueBuffer() { return _longValueBufferH; } @@ -413,7 +413,7 @@ public class TableImpl implements Table throw new IllegalArgumentException(withErrorContext( "Column with name " + name + " does not exist in this table")); } - + public boolean hasColumn(String name) { for(ColumnImpl column : _columns) { if(column.getName().equalsIgnoreCase(name)) { @@ -441,7 +441,7 @@ public class TableImpl implements Table } return _propertyMaps; } - + public List<IndexImpl> getIndexes() { return Collections.unmodifiableList(_indexes); } @@ -465,7 +465,7 @@ public class TableImpl implements Table throw new IllegalArgumentException(withErrorContext( "No primary key index found")); } - + public IndexImpl getForeignKeyIndex(Table otherTable) { for(IndexImpl index : _indexes) { if(index.isForeignKey() && (index.getReference() != null) && @@ -478,7 +478,7 @@ public class TableImpl implements Table "No foreign key reference to " + otherTable.getName() + " found")); } - + /** * @return All of the IndexData on this table (unmodifiable List) * @usage _advanced_method_ @@ -499,12 +499,12 @@ public class TableImpl implements Table return _indexCount; } - public IndexImpl findIndexForColumns(Collection<String> searchColumns, + public IndexImpl findIndexForColumns(Collection<String> searchColumns, IndexFeature feature) { IndexImpl partialIndex = null; for(IndexImpl index : _indexes) { - + Collection<? extends Index.Column> indexColumns = index.getColumns(); if(indexColumns.size() < searchColumns.size()) { continue; @@ -525,14 +525,14 @@ public class TableImpl implements Table } if(searchMatches) { - - if(exactMatch && ((feature != IndexFeature.EXACT_UNIQUE_ONLY) || + + if(exactMatch && ((feature != IndexFeature.EXACT_UNIQUE_ONLY) || index.isUnique())) { return index; } - if(!exactMatch && (feature == IndexFeature.ANY_MATCH) && - ((partialIndex == null) || + if(!exactMatch && (feature == IndexFeature.ANY_MATCH) && + ((partialIndex == null) || (indexColumns.size() < partialIndex.getColumnCount()))) { // this is a better partial index match partialIndex = index; @@ -542,7 +542,7 @@ public class TableImpl implements Table return partialIndex; } - + List<ColumnImpl> getAutoNumberColumns() { return _autoNumColumns; } @@ -557,7 +557,7 @@ public class TableImpl implements Table public CursorBuilder newCursor() { return new CursorBuilder(this); } - + public void reset() { getDefaultCursor().reset(); } @@ -583,14 +583,14 @@ public class TableImpl implements Table * Delete the row for the given rowId. * @usage _advanced_method_ */ - public void deleteRow(RowState rowState, RowIdImpl rowId) - throws IOException + public void deleteRow(RowState rowState, RowIdImpl rowId) + throws IOException { requireValidRowId(rowId); - + getPageChannel().startWrite(); try { - + // ensure that the relevant row state is up-to-date ByteBuffer rowBuffer = positionAtRowHeader(rowState, rowId); @@ -599,7 +599,7 @@ public class TableImpl implements Table return; } requireNonDeletedRow(rowState, rowId); - + // delete flag always gets set in the "header" row (even if data is on // overflow row) int pageNumber = rowState.getHeaderRowId().getPageNumber(); @@ -620,7 +620,7 @@ public class TableImpl implements Table rowValues = rowState.getRowCacheValues(); // check foreign keys before proceeding w/ deletion - _fkEnforcer.deleteRow(rowValues); + _fkEnforcer.deleteRow(rowValues); // move back to the header rowBuffer = positionAtRowHeader(rowState, rowId); @@ -636,7 +636,7 @@ public class TableImpl implements Table for(IndexData indexData : _indexDatas) { indexData.deleteRow(rowValues, rowId); } - + // make sure table def gets updated updateTableDefinition(-1); @@ -644,11 +644,11 @@ public class TableImpl implements Table getPageChannel().finishWrite(); } } - + public Row getNextRow() throws IOException { return getDefaultCursor().getNextRow(); } - + /** * Reads a single column from the given row. * @usage _advanced_method_ @@ -662,11 +662,11 @@ public class TableImpl implements Table "Given column " + column + " is not from this table")); } requireValidRowId(rowId); - + // position at correct row ByteBuffer rowBuffer = positionAtRowData(rowState, rowId); requireNonDeletedRow(rowState, rowId); - + return getRowColumn(getFormat(), rowBuffer, column, rowState, null); } @@ -711,7 +711,7 @@ public class TableImpl implements Table } return rtn; } - + /** * Reads the column data from the given row buffer. Leaves limit unchanged. * Caches the returned value in the rowState. @@ -743,10 +743,10 @@ public class TableImpl implements Table // we already have it, use it return cachedValue; } - + // reset position to row start rowBuffer.reset(); - + // locate the column data bytes int rowStart = rowBuffer.position(); int colDataPos = 0; @@ -757,9 +757,9 @@ public class TableImpl implements Table int dataStart = rowStart + format.OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET; colDataPos = dataStart + column.getFixedDataOffset(); colDataLen = column.getType().getFixedSize(column.getLength()); - + } else { - int varDataStart; + int varDataStart; int varDataEnd; if(format.SIZE_ROW_VAR_COL_OFFSET == 2) { @@ -799,13 +799,13 @@ public class TableImpl implements Table // to update the index on row deletion. note, most of the returned // values are immutable, except for binary data (returned as byte[]), // but binary data shouldn't be indexed anyway. - return rowState.setRowCacheValue(column.getColumnIndex(), + return rowState.setRowCacheValue(column.getColumnIndex(), column.read(columnData)); } catch(Exception e) { // cache "raw" row value. see note about caching above - rowState.setRowCacheValue(column.getColumnIndex(), + rowState.setRowCacheValue(column.getColumnIndex(), ColumnImpl.rawDataWrapper(columnData)); return rowState.handleRowError(column, columnData, e); @@ -814,7 +814,7 @@ public class TableImpl implements Table private static short[] readJumpTableVarColOffsets( RowState rowState, ByteBuffer rowBuffer, int rowStart, - NullMask nullMask) + NullMask nullMask) { short[] varColOffsets = rowState.getVarColOffsets(); if(varColOffsets != null) { @@ -824,14 +824,14 @@ public class TableImpl implements Table // calculate offsets using jump-table info int nullMaskSize = nullMask.byteSize(); int rowEnd = rowStart + rowBuffer.remaining() - 1; - int numVarCols = ByteUtil.getUnsignedByte(rowBuffer, + int numVarCols = ByteUtil.getUnsignedByte(rowBuffer, rowEnd - nullMaskSize); varColOffsets = new short[numVarCols + 1]; - + int rowLen = rowEnd - rowStart + 1; int numJumps = (rowLen - 1) / MAX_BYTE; int colOffset = rowEnd - nullMaskSize - numJumps - 1; - + // If last jump is a dummy value, ignore it if(((colOffset - rowStart - numVarCols) / MAX_BYTE) < numJumps) { numJumps--; @@ -840,17 +840,17 @@ public class TableImpl implements Table int jumpsUsed = 0; for(int i = 0; i < numVarCols + 1; i++) { - while((jumpsUsed < numJumps) && + while((jumpsUsed < numJumps) && (i == ByteUtil.getUnsignedByte( rowBuffer, rowEnd - nullMaskSize-jumpsUsed - 1))) { jumpsUsed++; } - + varColOffsets[i] = (short) (ByteUtil.getUnsignedByte(rowBuffer, colOffset - i) + (jumpsUsed * MAX_BYTE)); } - + rowState.setVarColOffsets(varColOffsets); return varColOffsets; } @@ -867,7 +867,7 @@ public class TableImpl implements Table // Number of columns in this row int columnCount = ByteUtil.getUnsignedVarInt( rowBuffer, getFormat().SIZE_ROW_COLUMN_COUNT); - + // read null mask NullMask nullMask = new NullMask(columnCount); rowBuffer.position(rowBuffer.limit() - nullMask.byteSize()); //Null mask at end @@ -880,11 +880,11 @@ public class TableImpl implements Table * Sets a new buffer to the correct row header page using the given rowState * according to the given rowId. Deleted state is * determined, but overflow row pointers are not followed. - * + * * @return a ByteBuffer of the relevant page, or null if row was invalid * @usage _advanced_method_ */ - public static ByteBuffer positionAtRowHeader(RowState rowState, + public static ByteBuffer positionAtRowHeader(RowState rowState, RowIdImpl rowId) throws IOException { @@ -894,7 +894,7 @@ public class TableImpl implements Table // this task has already been accomplished return rowBuffer; } - + if(!rowState.isValid()) { // this was an invalid page/row rowState.setStatus(RowStateStatus.AT_HEADER); @@ -919,17 +919,17 @@ public class TableImpl implements Table rowState.setStatus(RowStateStatus.AT_HEADER); return rowBuffer; } - + /** * Sets the position and limit in a new buffer using the given rowState * according to the given row number and row end, following overflow row * pointers as necessary. - * + * * @return a ByteBuffer narrowed to the actual row data, or null if row was * invalid or deleted * @usage _advanced_method_ */ - public static ByteBuffer positionAtRowData(RowState rowState, + public static ByteBuffer positionAtRowData(RowState rowState, RowIdImpl rowId) throws IOException { @@ -943,7 +943,7 @@ public class TableImpl implements Table ByteBuffer rowBuffer = rowState.getFinalPage(); int rowNum = rowState.getFinalRowId().getRowNumber(); JetFormat format = rowState.getTable().getFormat(); - + if(rowState.isAtFinalRow()) { // we've already found the final row data return PageChannel.narrowBuffer( @@ -951,9 +951,9 @@ public class TableImpl implements Table findRowStart(rowBuffer, rowNum, format), findRowEnd(rowBuffer, rowNum, format)); } - + while(true) { - + // note, we don't use findRowStart here cause we need the unmasked value short rowStart = rowBuffer.getShort(getRowStartOffset(rowNum, format)); short rowEnd = findRowEnd(rowBuffer, rowNum, format); @@ -972,7 +972,7 @@ public class TableImpl implements Table throw new IOException(rowState.getTable().withErrorContext( "invalid overflow row info")); } - + // Overflow page. the "row" data in the current page points to // another page/row int overflowRowNum = ByteUtil.getUnsignedByte(rowBuffer, rowStart); @@ -980,7 +980,7 @@ public class TableImpl implements Table rowBuffer = rowState.setOverflowRow( new RowIdImpl(overflowPageNum, overflowRowNum)); rowNum = overflowRowNum; - + } else { rowState.setStatus(RowStateStatus.AT_FINAL); @@ -1006,13 +1006,13 @@ public class TableImpl implements Table // next, determine how big the table def will be (in case it will be more // than one page) JetFormat format = creator.getFormat(); - int idxDataLen = (creator.getIndexCount() * - (format.SIZE_INDEX_DEFINITION + - format.SIZE_INDEX_COLUMN_BLOCK)) + + int idxDataLen = (creator.getIndexCount() * + (format.SIZE_INDEX_DEFINITION + + format.SIZE_INDEX_COLUMN_BLOCK)) + (creator.getLogicalIndexCount() * format.SIZE_INDEX_INFO_BLOCK); int colUmapLen = creator.getLongValueColumns().size() * 10; int totalTableDefSize = format.SIZE_TDEF_HEADER + - (format.SIZE_COLUMN_DEF_BLOCK * creator.getColumns().size()) + + (format.SIZE_COLUMN_DEF_BLOCK * creator.getColumns().size()) + idxDataLen + colUmapLen + format.SIZE_TDEF_TRAILER; // total up the amount of space used by the column and index names (2 @@ -1020,11 +1020,11 @@ public class TableImpl implements Table for(ColumnBuilder col : creator.getColumns()) { totalTableDefSize += DBMutator.calculateNameLength(col.getName()); } - + for(IndexBuilder idx : creator.getIndexes()) { totalTableDefSize += DBMutator.calculateNameLength(idx.getName()); } - + // now, create the table definition ByteBuffer buffer = PageChannel.createBuffer(Math.max(totalTableDefSize, @@ -1037,8 +1037,8 @@ public class TableImpl implements Table } // column definitions - ColumnImpl.writeDefinitions(creator, buffer); - + ColumnImpl.writeDefinitions(creator, buffer); + if(creator.hasIndexes()) { // index and index data definitions IndexData.writeDefinitions(creator, buffer); @@ -1059,7 +1059,7 @@ public class TableImpl implements Table } private static void writeTableDefinitionBuffer( - ByteBuffer buffer, int tdefPageNumber, + ByteBuffer buffer, int tdefPageNumber, TableMutator mutator, List<Integer> reservedPages) throws IOException { @@ -1070,7 +1070,7 @@ public class TableImpl implements Table // write table buffer to database if(totalTableDefSize <= format.PAGE_SIZE) { - + // easy case, fits on one page // overwrite page free space @@ -1080,7 +1080,7 @@ public class TableImpl implements Table // Write the tdef page to disk. buffer.clear(); pageChannel.writePage(buffer, tdefPageNumber); - + } else { // need to split across multiple pages @@ -1092,13 +1092,13 @@ public class TableImpl implements Table // reset for next write partialTdef.clear(); - + if(nextTdefPageNumber == PageChannel.INVALID_PAGE_NUMBER) { - + // this is the first page. note, the first page already has the // page header, so no need to write it here nextTdefPageNumber = tdefPageNumber; - + } else { // write page header @@ -1130,9 +1130,9 @@ public class TableImpl implements Table // write partial page to disk pageChannel.writePage(partialTdef, curTdefPageNumber); } - + } - + } /** @@ -1166,7 +1166,7 @@ public class TableImpl implements Table int umapPos = -1; boolean success = false; try { - + //// // update various bits of the table def ByteUtil.forward(tableBuffer, 29); @@ -1176,7 +1176,7 @@ public class TableImpl implements Table tableBuffer.putShort((short)(_columns.size() + 1)); // move to end of column def blocks - tableBuffer.position(format.SIZE_TDEF_HEADER + + tableBuffer.position(format.SIZE_TDEF_HEADER + (_indexCount * format.SIZE_INDEX_DEFINITION) + (_columns.size() * format.SIZE_COLUMN_DEF_BLOCK)); @@ -1193,9 +1193,9 @@ public class TableImpl implements Table } else { // find the fixed offset for(ColumnImpl col : _columns) { - if(!col.isVariableLength() && + if(!col.isVariableLength() && (col.getFixedDataOffset() >= fixedOffset)) { - fixedOffset = col.getFixedDataOffset() + + fixedOffset = col.getFixedDataOffset() + col.getType().getFixedSize(col.getLength()); } } @@ -1224,7 +1224,7 @@ public class TableImpl implements Table colState.setUmapFreeRowNumber((byte)(rowNum + 1)); // skip past index defs - ByteUtil.forward(tableBuffer, (_indexCount * + ByteUtil.forward(tableBuffer, (_indexCount * format.SIZE_INDEX_COLUMN_BLOCK)); ByteUtil.forward(tableBuffer, (_logicalIndexCount * format.SIZE_INDEX_INFO_BLOCK)); @@ -1237,7 +1237,7 @@ public class TableImpl implements Table ByteUtil.forward(tableBuffer, -2); break; } - + ByteUtil.forward(tableBuffer, 8); // keep reading ... @@ -1260,7 +1260,7 @@ public class TableImpl implements Table //// // write updated table def back to the database - writeTableDefinitionBuffer(tableBuffer, _tableDefPageNumber, mutator, + writeTableDefinitionBuffer(tableBuffer, _tableDefPageNumber, mutator, mutator.getNextPages()); success = true; @@ -1321,7 +1321,7 @@ public class TableImpl implements Table //// // calculate how much more space we need in the table def - mutator.addTdefLen(format.SIZE_INDEX_DEFINITION + + mutator.addTdefLen(format.SIZE_INDEX_DEFINITION + format.SIZE_INDEX_COLUMN_BLOCK); //// @@ -1332,14 +1332,14 @@ public class TableImpl implements Table IndexData newIdxData = null; boolean success = false; try { - + //// // update various bits of the table def ByteUtil.forward(tableBuffer, 39); tableBuffer.putInt(_indexCount + 1); // move to end of index data def blocks - tableBuffer.position(format.SIZE_TDEF_HEADER + + tableBuffer.position(format.SIZE_TDEF_HEADER + (_indexCount * format.SIZE_INDEX_DEFINITION)); // write index row count definition (empty initially) @@ -1347,12 +1347,12 @@ public class TableImpl implements Table IndexData.writeRowCountDefinitions(mutator, tableBuffer, 1); // skip columns and column names - ByteUtil.forward(tableBuffer, + ByteUtil.forward(tableBuffer, (_columns.size() * format.SIZE_COLUMN_DEF_BLOCK)); skipNames(tableBuffer, _columns.size()); // move to end of current index datas - ByteUtil.forward(tableBuffer, (_indexCount * + ByteUtil.forward(tableBuffer, (_indexCount * format.SIZE_INDEX_COLUMN_BLOCK)); // allocate usage maps and root page @@ -1380,7 +1380,7 @@ public class TableImpl implements Table //// // write updated table def back to the database - writeTableDefinitionBuffer(tableBuffer, _tableDefPageNumber, mutator, + writeTableDefinitionBuffer(tableBuffer, _tableDefPageNumber, mutator, mutator.getNextPages()); success = true; @@ -1397,7 +1397,7 @@ public class TableImpl implements Table for(IndexData.ColumnDescriptor iCol : newIdxData.getColumns()) { _indexColumns.add(iCol.getColumn()); } - + ++_indexCount; _indexDatas.add(newIdxData); @@ -1425,7 +1425,7 @@ public class TableImpl implements Table col.setRowValue(rowVals, col.getRowValue(row)); } - IndexData.commitAll( + IndexData.commitAll( idxData.prepareAddRow(rowVals, (RowIdImpl)row.getId(), null)); } @@ -1456,26 +1456,26 @@ public class TableImpl implements Table IndexImpl newIdx = null; boolean success = false; try { - + //// // update various bits of the table def ByteUtil.forward(tableBuffer, 35); tableBuffer.putInt(_logicalIndexCount + 1); // move to end of index data def blocks - tableBuffer.position(format.SIZE_TDEF_HEADER + + tableBuffer.position(format.SIZE_TDEF_HEADER + (_indexCount * format.SIZE_INDEX_DEFINITION)); // skip columns and column names - ByteUtil.forward(tableBuffer, + ByteUtil.forward(tableBuffer, (_columns.size() * format.SIZE_COLUMN_DEF_BLOCK)); skipNames(tableBuffer, _columns.size()); // move to end of current index datas - ByteUtil.forward(tableBuffer, (_indexCount * + ByteUtil.forward(tableBuffer, (_indexCount * format.SIZE_INDEX_COLUMN_BLOCK)); // move to end of current indexes - ByteUtil.forward(tableBuffer, (_logicalIndexCount * + ByteUtil.forward(tableBuffer, (_logicalIndexCount * format.SIZE_INDEX_INFO_BLOCK)); int idxDefPos = tableBuffer.position(); @@ -1494,10 +1494,10 @@ public class TableImpl implements Table tableBuffer.position(idxDefPos); newIdx = new IndexImpl(tableBuffer, _indexDatas, format); newIdx.setName(index.getName()); - + //// // write updated table def back to the database - writeTableDefinitionBuffer(tableBuffer, _tableDefPageNumber, mutator, + writeTableDefinitionBuffer(tableBuffer, _tableDefPageNumber, mutator, mutator.getNextPages()); success = true; @@ -1547,7 +1547,7 @@ public class TableImpl implements Table private static void skipNames(ByteBuffer tableBuffer, int count) { for(int i = 0; i < count; ++i) { ByteUtil.forward(tableBuffer, tableBuffer.getShort()); - } + } } private ByteBuffer loadCompleteTableDefinitionBufferForUpdate( @@ -1616,7 +1616,7 @@ public class TableImpl implements Table } if(umapPageNumber == PageChannel.INVALID_PAGE_NUMBER) { - + // didn't find any existing pages, need to create a new one umapPageNumber = pageChannel.allocateNewPage(); freeSpace = format.DATA_PAGE_INITIAL_FREE_SPACE; @@ -1631,20 +1631,26 @@ public class TableImpl implements Table umapBuf.putShort(getRowStartOffset(umapRowNum, format), (short)rowStart); umapBuf.put(rowStart, UsageMap.MAP_TYPE_INLINE); + int dataOffset = rowStart + 1; if(firstUsedPage != null) { // fill in the first used page of the usage map - umapBuf.putInt(rowStart + 1, firstUsedPage); - umapBuf.put(rowStart + 5, (byte)1); + umapBuf.putInt(dataOffset, firstUsedPage); + dataOffset += 4; + umapBuf.put(dataOffset, (byte)1); + dataOffset++; } - rowStart -= umapRowLength; + // zero remaining row data + ByteUtil.clearRange(umapBuf, dataOffset, (rowStart + umapRowLength)); + + rowStart -= umapRowLength; ++umapRowNum; } // finish the page freeSpace -= totalUmapSpaceUsage; umapBuf.putShort(format.OFFSET_FREE_SPACE, (short)freeSpace); - umapBuf.putShort(format.OFFSET_NUM_ROWS_ON_DATA_PAGE, + umapBuf.putShort(format.OFFSET_NUM_ROWS_ON_DATA_PAGE, (short)umapRowNum); pageChannel.writePage(umapBuf, umapPageNumber); @@ -1663,8 +1669,8 @@ public class TableImpl implements Table for(ColumnImpl col : _columns) { col.collectUsageMapPages(pages); } - } - + } + /** * @param buffer Buffer to write to */ @@ -1708,7 +1714,7 @@ public class TableImpl implements Table buffer.put((byte) 0); //Unknown buffer.putInt(0); //Next TDEF page pointer } - + /** * Writes the given name into the given buffer in the format as expected by * {@link #readName}. @@ -1719,7 +1725,7 @@ public class TableImpl implements Table buffer.putShort((short) encName.remaining()); buffer.put(encName); } - + /** * Create the usage map definition page buffer. The "used pages" map is in * row 0, the "pages with free space" map is in row 1. Index usage maps are @@ -1744,7 +1750,7 @@ public class TableImpl implements Table int freeSpace = 0; int rowStart = 0; int umapRowNum = 0; - + for(int i = 0; i < umapNum; ++i) { if(umapBuf == null) { @@ -1767,7 +1773,7 @@ public class TableImpl implements Table } umapBuf.putShort(getRowStartOffset(umapRowNum, format), (short)rowStart); - + if(i == 0) { // table "owned pages" map definition @@ -1782,9 +1788,9 @@ public class TableImpl implements Table // index umap int indexIdx = i - 2; - TableMutator.IndexDataState idxDataState = + TableMutator.IndexDataState idxDataState = creator.getIndexDataStates().get(indexIdx); - + // allocate root page for the index int rootPageNumber = pageChannel.allocateNewPage(); @@ -1806,19 +1812,19 @@ public class TableImpl implements Table lvalColIdx /= 2; ColumnBuilder lvalCol = lvalCols.get(lvalColIdx); - TableMutator.ColumnState colState = + TableMutator.ColumnState colState = creator.getColumnState(lvalCol); umapBuf.put(rowStart, UsageMap.MAP_TYPE_INLINE); - if((umapType == 1) && + if((umapType == 1) && (umapPageNumber != colState.getUmapPageNumber())) { // we want to force both usage maps for a column to be on the same // data page, so just discard the previous one we wrote --i; umapType = 0; } - + if(umapType == 0) { // lval column "owned pages" usage map colState.setUmapOwnedRowNumber((byte)umapRowNum); @@ -1836,7 +1842,7 @@ public class TableImpl implements Table if((freeSpace <= umapSpaceUsage) || (i == (umapNum - 1))) { // finish current page umapBuf.putShort(format.OFFSET_FREE_SPACE, (short)freeSpace); - umapBuf.putShort(format.OFFSET_NUM_ROWS_ON_DATA_PAGE, + umapBuf.putShort(format.OFFSET_NUM_ROWS_ON_DATA_PAGE, (short)umapRowNum); pageChannel.writePage(umapBuf, umapPageNumber); umapBuf = null; @@ -1853,7 +1859,7 @@ public class TableImpl implements Table umapBuf.putShort((short)freeSpace); //Free space in page umapBuf.putInt(0); //Table definition umapBuf.putInt(0); //Unknown - umapBuf.putShort((short)0); //Number of records on this page + umapBuf.putShort((short)0); //Number of records on this page return umapBuf; } @@ -1882,14 +1888,14 @@ public class TableImpl implements Table } return tableBuffer; } - + private ByteBuffer expandTableBuffer(ByteBuffer tableBuffer) { ByteBuffer newBuffer = PageChannel.createBuffer( tableBuffer.capacity() + getFormat().PAGE_SIZE - 8); newBuffer.put(tableBuffer); return newBuffer; } - + private void readColumnDefinitions(ByteBuffer tableBuffer, short columnCount) throws IOException { @@ -1901,8 +1907,8 @@ public class TableImpl implements Table List<String> colNames = new ArrayList<String>(columnCount); for (int i = 0; i < columnCount; i++) { colNames.add(readName(tableBuffer)); - } - + } + int dispIndex = 0; for (int i = 0; i < columnCount; i++) { ColumnImpl column = ColumnImpl.create(this, tableBuffer, @@ -1951,18 +1957,18 @@ public class TableImpl implements Table for (int i = 0; i < _logicalIndexCount; i++) { _indexes.get(i).setName(readName(tableBuffer)); } - + Collections.sort(_indexes); } - - private boolean readColumnUsageMaps(ByteBuffer tableBuffer) + + private boolean readColumnUsageMaps(ByteBuffer tableBuffer) throws IOException { short umapColNum = tableBuffer.getShort(); if(umapColNum == IndexData.COLUMN_UNUSED) { return false; } - + int pos = tableBuffer.position(); UsageMap colOwnedPages = null; UsageMap colFreeSpacePages = null; @@ -1974,10 +1980,10 @@ public class TableImpl implements Table colOwnedPages = null; colFreeSpacePages = null; tableBuffer.position(pos + 8); - LOG.warn(withErrorContext("Invalid column " + umapColNum + + LOG.warn(withErrorContext("Invalid column " + umapColNum + " usage map definition: " + e)); } - + for(ColumnImpl col : _columns) { if(col.getColumnNumber() == umapColNum) { col.setUsageMaps(colOwnedPages, colFreeSpacePages); @@ -2001,7 +2007,7 @@ public class TableImpl implements Table // possibly invalidate the add row buffer if a different data buffer is // being written (e.g. this happens during deleteRow) _addRowBufferH.possiblyInvalidate(pageNumber, pageBuffer); - + // update modification count so any active RowStates can keep themselves // up-to-date ++_modCount; @@ -2009,27 +2015,27 @@ public class TableImpl implements Table /** * Returns a name read from the buffer at the current position. The - * expected name format is the name length followed by the name + * expected name format is the name length followed by the name * encoded using the {@link JetFormat#CHARSET} */ - private String readName(ByteBuffer buffer) { + private String readName(ByteBuffer buffer) { int nameLength = readNameLength(buffer); byte[] nameBytes = ByteUtil.getBytes(buffer, nameLength); - return ColumnImpl.decodeUncompressedText(nameBytes, + return ColumnImpl.decodeUncompressedText(nameBytes, getDatabase().getCharset()); } - + /** * Returns a name length read from the buffer at the current position. */ - private int readNameLength(ByteBuffer buffer) { + private int readNameLength(ByteBuffer buffer) { return ByteUtil.getUnsignedVarInt(buffer, getFormat().SIZE_NAME_LENGTH); } - + public Object[] asRow(Map<String,?> rowMap) { return asRow(rowMap, null, false); } - + /** * Converts a map of columnName -> columnValue to an array of row values * appropriate for a call to {@link #addRow(Object...)}, where the generated @@ -2040,7 +2046,7 @@ public class TableImpl implements Table public Object[] asRowWithRowId(Map<String,?> rowMap) { return asRow(rowMap, null, true); } - + public Object[] asUpdateRow(Map<String,?> rowMap) { return asRow(rowMap, Column.KEEP_VALUE, false); } @@ -2057,7 +2063,7 @@ public class TableImpl implements Table /** * Converts a map of columnName -> columnValue to an array of row values. */ - private Object[] asRow(Map<String,?> rowMap, Object defaultValue, + private Object[] asRow(Map<String,?> rowMap, Object defaultValue, boolean returnRowId) { int len = _columns.size(); @@ -2081,13 +2087,13 @@ public class TableImpl implements Table } return row; } - + public Object[] addRow(Object... row) throws IOException { return addRows(Collections.singletonList(row), false).get(0); } - public <M extends Map<String,Object>> M addRowFromMap(M row) - throws IOException + public <M extends Map<String,Object>> M addRowFromMap(M row) + throws IOException { Object[] rowValues = asRow(row); @@ -2096,20 +2102,20 @@ public class TableImpl implements Table returnRowValues(row, rowValues, _autoNumColumns); return row; } - - public List<? extends Object[]> addRows(List<? extends Object[]> rows) - throws IOException + + public List<? extends Object[]> addRows(List<? extends Object[]> rows) + throws IOException { return addRows(rows, true); } - - public <M extends Map<String,Object>> List<M> addRowsFromMaps(List<M> rows) - throws IOException + + public <M extends Map<String,Object>> List<M> addRowsFromMaps(List<M> rows) + throws IOException { List<Object[]> rowValuesList = new ArrayList<Object[]>(rows.size()); for(Map<String,Object> row : rows) { rowValuesList.add(asRow(row)); - } + } addRows(rowValuesList); @@ -2146,12 +2152,12 @@ public class TableImpl implements Table getPageChannel().startWrite(); try { - + ByteBuffer dataPage = null; int pageNumber = PageChannel.INVALID_PAGE_NUMBER; int updateCount = 0; int autoNumAssignCount = 0; - WriteRowState writeRowState = + WriteRowState writeRowState = (!_autoNumColumns.isEmpty() ? new WriteRowState() : null); try { @@ -2179,7 +2185,7 @@ public class TableImpl implements Table // handle various value massaging activities for(ColumnImpl column : _columns) { - if(!column.isAutoNumber()) { + if(!column.isAutoNumber()) { // pass input value through column validator column.setRowValue(row, column.validate(column.getRowValue(row))); } @@ -2188,11 +2194,11 @@ public class TableImpl implements Table // fill in autonumbers handleAutoNumbersForAdd(row, writeRowState); ++autoNumAssignCount; - + // write the row of data to a temporary buffer ByteBuffer rowData = createRow( row, _writeRowBufferH.getPageBuffer(getPageChannel())); - + int rowSize = rowData.remaining(); if (rowSize > getFormat().MAX_ROW_SIZE) { throw new IOException(withErrorContext( @@ -2237,7 +2243,7 @@ public class TableImpl implements Table dataPage.put(rowData); // return rowTd if desired - if((row.length > numCols) && + if((row.length > numCols) && (row[numCols] == ColumnImpl.RETURN_ROW_ID)) { row[numCols] = rowId; } @@ -2246,7 +2252,7 @@ public class TableImpl implements Table } writeDataPage(dataPage, pageNumber); - + // Update tdef page updateTableDefinition(rows.size()); @@ -2259,12 +2265,12 @@ public class TableImpl implements Table // recover them so we don't get ugly "holes" restoreAutoNumbersFromAdd(rows.get(autoNumAssignCount - 1)); } - + if(!isBatchWrite) { // just re-throw the original exception if(rowWriteFailure instanceof IOException) { throw (IOException)rowWriteFailure; - } + } throw (RuntimeException)rowWriteFailure; } @@ -2276,12 +2282,12 @@ public class TableImpl implements Table updateCount = 0; } else if(updateCount > 0) { - + // attempt to flush the rows already written to disk try { writeDataPage(dataPage, pageNumber); - + // Update tdef page updateTableDefinition(updateCount); @@ -2291,7 +2297,7 @@ public class TableImpl implements Table // write failure). we don't know the status of any rows at this // point (and the original failure is probably irrelevant) LOG.warn(withErrorContext( - "Secondary row failure which preceded the write failure"), + "Secondary row failure which preceded the write failure"), rowWriteFailure); updateCount = 0; rowWriteFailure = flushFailure; @@ -2306,7 +2312,7 @@ public class TableImpl implements Table } finally { getPageChannel().finishWrite(); } - + return rows; } @@ -2316,11 +2322,11 @@ public class TableImpl implements Table return true; } t = t.getCause(); - } + } // some other sort of exception which is not a write failure return false; } - + public Row updateRow(Row row) throws IOException { return updateRowFromMap( getDefaultCursor().getRowState(), (RowIdImpl)row.getId(), row); @@ -2344,8 +2350,8 @@ public class TableImpl implements Table * @throws IllegalStateException if the given row is not valid, or deleted. * @usage _intermediate_method_ */ - public void updateValue(Column column, RowId rowId, Object value) - throws IOException + public void updateValue(Column column, RowId rowId, Object value) + throws IOException { Object[] row = new Object[_columns.size()]; Arrays.fill(row, Column.KEEP_VALUE); @@ -2355,8 +2361,8 @@ public class TableImpl implements Table } public <M extends Map<String,Object>> M updateRowFromMap( - RowState rowState, RowIdImpl rowId, M row) - throws IOException + RowState rowState, RowIdImpl rowId, M row) + throws IOException { Object[] rowValues = updateRow(rowState, rowId, asUpdateRow(row)); returnRowValues(row, rowValues, _columns); @@ -2367,14 +2373,14 @@ public class TableImpl implements Table * Update the row for the given rowId. * @usage _advanced_method_ */ - public Object[] updateRow(RowState rowState, RowIdImpl rowId, Object... row) - throws IOException + public Object[] updateRow(RowState rowState, RowIdImpl rowId, Object... row) + throws IOException { requireValidRowId(rowId); - + getPageChannel().startWrite(); try { - + // ensure that the relevant row state is up-to-date ByteBuffer rowBuffer = positionAtRowData(rowState, rowId); int oldRowSize = rowBuffer.remaining(); @@ -2390,7 +2396,7 @@ public class TableImpl implements Table // hang on to the raw values of var length columns we are "keeping". this // will allow us to re-use pre-written var length data, which can save // space for things like long value columns. - Map<ColumnImpl,byte[]> keepRawVarValues = + Map<ColumnImpl,byte[]> keepRawVarValues = (!_varColumns.isEmpty() ? new HashMap<ColumnImpl,byte[]>() : null); // handle various value massaging activities @@ -2403,11 +2409,11 @@ public class TableImpl implements Table Object rowValue = column.getRowValue(row); if(rowValue == Column.KEEP_VALUE) { - + // fill in any "keep value" fields (restore old value) rowValue = getRowColumn(getFormat(), rowBuffer, column, rowState, keepRawVarValues); - + } else { // set oldValue to something that could not possibly be a real value @@ -2424,7 +2430,7 @@ public class TableImpl implements Table if(oldValue != rowValue) { // pass input value through column validator rowValue = column.validate(rowValue); - } + } } column.setRowValue(row, rowValue); @@ -2455,7 +2461,7 @@ public class TableImpl implements Table // prepare index updates for(IndexData indexData : _indexDatas) { - idxChange = indexData.prepareUpdateRow(oldRowValues, rowId, row, + idxChange = indexData.prepareUpdateRow(oldRowValues, rowId, row, idxChange); } @@ -2467,7 +2473,7 @@ public class TableImpl implements Table throw ce; } } - + // see if we can squeeze the new row data into the existing row rowBuffer.reset(); int rowSize = newRowData.remaining(); @@ -2487,11 +2493,11 @@ public class TableImpl implements Table } else { // bummer, need to find a new page for the data - dataPage = findFreeRowSpace(rowSize, null, + dataPage = findFreeRowSpace(rowSize, null, PageChannel.INVALID_PAGE_NUMBER); pageNumber = _addRowBufferH.getPageNumber(); - RowIdImpl headerRowId = rowState.getHeaderRowId(); + RowIdImpl headerRowId = rowState.getHeaderRowId(); ByteBuffer headerPage = rowState.getHeaderPage(); if(pageNumber == headerRowId.getPageNumber()) { // new row is on the same page as header row, share page @@ -2535,8 +2541,8 @@ public class TableImpl implements Table return row; } - - private ByteBuffer findFreeRowSpace(int rowSize, ByteBuffer dataPage, + + private ByteBuffer findFreeRowSpace(int rowSize, ByteBuffer dataPage, int pageNumber) throws IOException { @@ -2546,7 +2552,7 @@ public class TableImpl implements Table if(dataPage == null) { // find owned page w/ free space - dataPage = findFreeRowSpace(_ownedPages, _freeSpacePages, + dataPage = findFreeRowSpace(_ownedPages, _freeSpacePages, _addRowBufferH); if(dataPage == null) { @@ -2602,7 +2608,7 @@ public class TableImpl implements Table return null; } - + /** * Updates the table definition after rows are modified. */ @@ -2611,7 +2617,7 @@ public class TableImpl implements Table // load table definition ByteBuffer tdefPage = _tableDefBufferH.setPage(getPageChannel(), _tableDefPageNumber); - + // make sure rowcount and autonumber are up-to-date _rowCount += rowCountInc; tdefPage.putInt(getFormat().OFFSET_NUM_ROWS, _rowCount); @@ -2634,7 +2640,7 @@ public class TableImpl implements Table // write modified table definition getPageChannel().writePage(tdefPage, _tableDefPageNumber); } - + /** * Create a new data page * @return Page number of the new page @@ -2653,7 +2659,7 @@ public class TableImpl implements Table _freeSpacePages.addPageNumber(pageNumber); return dataPage; } - + protected ByteBuffer createRow(Object[] rowArray, ByteBuffer buffer) throws IOException { @@ -2663,7 +2669,7 @@ public class TableImpl implements Table /** * Serialize a row of Objects into a byte buffer. - * + * * @param rowArray row data, expected to be correct length for this table * @param buffer buffer to which to write the row data * @param minRowSize min size for result row @@ -2672,13 +2678,13 @@ public class TableImpl implements Table * @return the given buffer, filled with the row data */ private ByteBuffer createRow(Object[] rowArray, ByteBuffer buffer, - int minRowSize, + int minRowSize, Map<ColumnImpl,byte[]> rawVarValues) throws IOException { buffer.putShort(_maxColumnCount); NullMask nullMask = new NullMask(_maxColumnCount); - + //Fixed length column data comes first int fixedDataStart = buffer.position(); int fixedDataEnd = fixedDataStart; @@ -2687,19 +2693,19 @@ public class TableImpl implements Table if(col.isVariableLength()) { continue; } - + Object rowValue = col.getRowValue(rowArray); if (col.storeInNullMask()) { - + if(col.writeToNullMask(rowValue)) { nullMask.markNotNull(col); } rowValue = null; } - + if(rowValue != null) { - + // we have a value to write nullMask.markNotNull(col); @@ -2717,13 +2723,13 @@ public class TableImpl implements Table // keep track of the end of fixed data if(buffer.position() > fixedDataEnd) { fixedDataEnd = buffer.position(); - } - + } + } // reposition at end of fixed data buffer.position(fixedDataEnd); - + // only need this info if this table contains any var length data if(_maxVarColumnCount > 0) { @@ -2745,7 +2751,7 @@ public class TableImpl implements Table maxRowSize -= getFormat().SIZE_LONG_VALUE_DEF; } } - + //Now write out variable length column data short[] varColumnOffsets = new short[_maxVarColumnCount]; int varColumnOffsetsIndex = 0; @@ -2758,7 +2764,7 @@ public class TableImpl implements Table byte[] rawValue = null; ByteBuffer varDataBuf = null; - if(((rawValue = rawVarValues.get(varCol)) != null) && + if(((rawValue = rawVarValues.get(varCol)) != null) && (rawValue.length <= maxRowSize)) { // save time and potentially db space, re-use raw value varDataBuf = ByteBuffer.wrap(rawValue); @@ -2780,7 +2786,7 @@ public class TableImpl implements Table // the max row size throw new IOException(withErrorContext( "Row size " + buffer.limit() + " is too large")); - } + } } // we do a loop here so that we fill in offsets for deleted columns @@ -2839,14 +2845,14 @@ public class TableImpl implements Table Object inRowValue = getInputAutoNumberRowValue(enableInsert, col, row); ColumnImpl.AutoNumberGenerator autoNumGen = col.getAutoNumberGenerator(); - Object rowValue = ((inRowValue == null) ? + Object rowValue = ((inRowValue == null) ? autoNumGen.getNext(writeRowState) : autoNumGen.handleInsert(writeRowState, inRowValue)); col.setRowValue(row, rowValue); } } - + /** * Fill in all autonumber column values for update. */ @@ -2866,7 +2872,7 @@ public class TableImpl implements Table // enabled) Object inRowValue = getInputAutoNumberRowValue(enableInsert, col, row); - Object rowValue = + Object rowValue = ((inRowValue == null) ? getRowColumn(getFormat(), rowBuffer, col, rowState, null) : col.getAutoNumberGenerator().handleInsert(rowState, inRowValue)); @@ -2893,7 +2899,7 @@ public class TableImpl implements Table } return inRowValue; } - + /** * Restores all autonumber column values from a failed add row. */ @@ -2946,7 +2952,7 @@ public class TableImpl implements Table // restores the last used auto number _lastLongAutoNumber = lastLongAutoNumber - 1; } - + int getNextComplexTypeAutoNumber() { // note, the saved value is the last one handed out, so pre-increment return ++_lastComplexTypeAutoNumber; @@ -2967,7 +2973,7 @@ public class TableImpl implements Table // restores the last used auto number _lastComplexTypeAutoNumber = lastComplexTypeAutoNumber - 1; } - + @Override public String toString() { return CustomToStringStyle.builder(this) @@ -2982,7 +2988,7 @@ public class TableImpl implements Table .append("ownedPages", _ownedPages) .toString(); } - + /** * @return A simple String representation of the entire table in * tab-delimited format @@ -2991,7 +2997,7 @@ public class TableImpl implements Table public String display() throws IOException { return display(Long.MAX_VALUE); } - + /** * @param limit Maximum number of rows to display * @return A simple String representation of the entire table in @@ -3014,11 +3020,11 @@ public class TableImpl implements Table */ public static int addDataPageRow(ByteBuffer dataPage, int rowSize, - JetFormat format, + JetFormat format, int rowFlags) { int rowSpaceUsage = getRowSpaceUsage(rowSize, format); - + // Decrease free space record. short freeSpaceInPage = dataPage.getShort(format.OFFSET_FREE_SPACE); dataPage.putShort(format.OFFSET_FREE_SPACE, (short) (freeSpaceInPage - @@ -3034,7 +3040,7 @@ public class TableImpl implements Table rowLocation -= rowSize; // write row position - dataPage.putShort(getRowStartOffset(rowCount, format), + dataPage.putShort(getRowStartOffset(rowCount, format), (short)(rowLocation | rowFlags)); // set position for row data @@ -3066,7 +3072,7 @@ public class TableImpl implements Table "Given rowId is invalid: " + rowId)); } } - + /** * @throws IllegalStateException if the given row is invalid or deleted */ @@ -3081,14 +3087,14 @@ public class TableImpl implements Table "Row is deleted: " + rowId)); } } - + /** * @usage _advanced_method_ */ public static boolean isDeletedRow(short rowStart) { return ((rowStart & DELETED_ROW_MASK) != 0); } - + /** * @usage _advanced_method_ */ @@ -3102,7 +3108,7 @@ public class TableImpl implements Table public static short cleanRowStart(short rowStart) { return (short)(rowStart & OFFSET_MASK); } - + /** * @usage _advanced_method_ */ @@ -3120,7 +3126,7 @@ public class TableImpl implements Table { return format.OFFSET_ROW_START + (format.SIZE_ROW_LOCATION * rowNum); } - + /** * @usage _advanced_method_ */ @@ -3262,7 +3268,7 @@ public class TableImpl implements Table private ErrorHandler _errorHandler; /** cached variable column offsets for jump-table based rows */ private short[] _varColOffsets; - + private RowState(TempBufferHolder.Type headerType) { _headerRowBufferH = TempPageHolder.newHolder(headerType); _rowValues = new Object[TableImpl.this.getColumnCount()]; @@ -3281,7 +3287,7 @@ public class TableImpl implements Table public void setErrorHandler(ErrorHandler newErrorHandler) { _errorHandler = newErrorHandler; } - + public void reset() { resetAutoNumber(); _finalRowId = null; @@ -3300,7 +3306,7 @@ public class TableImpl implements Table public boolean isUpToDate() { return(TableImpl.this._modCount == _lastModCount); } - + private void checkForModification() { if(!isUpToDate()) { reset(); @@ -3314,7 +3320,7 @@ public class TableImpl implements Table _lastModCount = TableImpl.this._modCount; } } - + private ByteBuffer getFinalPage() throws IOException { @@ -3339,11 +3345,11 @@ public class TableImpl implements Table public boolean isValid() { return(_rowStatus.ordinal() >= RowStatus.VALID.ordinal()); } - + public boolean isDeleted() { return(_rowStatus == RowStatus.DELETED); } - + public boolean isOverflow() { return(_rowStatus == RowStatus.OVERFLOW); } @@ -3351,19 +3357,19 @@ public class TableImpl implements Table public boolean isHeaderPageNumberValid() { return(_rowStatus.ordinal() > RowStatus.INVALID_PAGE.ordinal()); } - + public boolean isHeaderRowNumberValid() { return(_rowStatus.ordinal() > RowStatus.INVALID_ROW.ordinal()); } - + private void setStatus(RowStateStatus status) { _status = status; } - + public boolean isAtHeaderRow() { return(_status.ordinal() >= RowStateStatus.AT_HEADER.ordinal()); } - + public boolean isAtFinalRow() { return(_status.ordinal() >= RowStateStatus.AT_FINAL.ordinal()); } @@ -3380,7 +3386,7 @@ public class TableImpl implements Table // modified externally and therefore could return an incorrect value return(ColumnImpl.isImmutableValue(value) ? value : null); } - + public Object[] getRowCacheValues() { return dupeRow(_rowValues, _rowValues.length); } @@ -3399,7 +3405,7 @@ public class TableImpl implements Table private void setVarColOffsets(short[] varColOffsets) { _varColOffsets = varColOffsets; } - + public RowIdImpl getHeaderRowId() { return _headerRowId; } @@ -3407,7 +3413,7 @@ public class TableImpl implements Table public int getRowsOnHeaderPage() { return _rowsOnHeaderPage; } - + private ByteBuffer getHeaderPage() throws IOException { @@ -3436,11 +3442,11 @@ public class TableImpl implements Table setRowStatus(RowStatus.INVALID_PAGE); return null; } - + _finalRowBuffer = _headerRowBufferH.setPage(getPageChannel(), pageNumber); _rowsOnHeaderPage = getRowsOnDataPage(_finalRowBuffer, getFormat()); - + if((rowNumber < 0) || (rowNumber >= _rowsOnHeaderPage)) { setRowStatus(RowStatus.INVALID_ROW); return null; @@ -3475,7 +3481,7 @@ public class TableImpl implements Table { return getErrorHandler().handleRowError(column, columnData, this, error); - } + } @Override public String toString() { @@ -3485,5 +3491,5 @@ public class TableImpl implements Table .toString(); } } - + } |