List of usage examples for java.nio ByteBuffer putInt
public abstract ByteBuffer putInt(int value);
From source file:org.apache.hadoop.hive.serde2.compression.SnappyCompDe.java
/** * Compress a set of columns./*from ww w . j a va 2 s .c om*/ * * The header contains a compressed array of data types. * The body contains compressed columns and their metadata. * The footer contains a compressed array of chunk sizes. The final four bytes of the footer encode the byte size of that compressed array. * * @param colSet * * @return ByteBuffer representing the compressed set. */ @Override public ByteBuffer compress(ColumnBuffer[] colSet) { // Many compression libraries allow you to avoid allocation of intermediate arrays. // To use these API, we need to preallocate the output container. // Reserve space for the header. int[] dataType = new int[colSet.length]; int maxCompressedSize = Snappy.maxCompressedLength(4 * dataType.length); // Reserve space for the compressed nulls BitSet for each column. maxCompressedSize += colSet.length * Snappy.maxCompressedLength((colSet.length / 8) + 1); // Track the length of `List<Integer> compressedSize` which will be declared later. int uncompressedFooterLength = 1 + 2 * colSet.length; for (int colNum = 0; colNum < colSet.length; ++colNum) { // Reserve space for the compressed columns. dataType[colNum] = colSet[colNum].getType().toTType().getValue(); switch (TTypeId.findByValue(dataType[colNum])) { case BOOLEAN_TYPE: maxCompressedSize += Integer.SIZE / Byte.SIZE; // This is for the encoded length. maxCompressedSize += Snappy.maxCompressedLength((colSet.length / 8) + 1); break; case TINYINT_TYPE: maxCompressedSize += Snappy.maxCompressedLength(colSet.length); break; case SMALLINT_TYPE: maxCompressedSize += Snappy.maxCompressedLength(colSet.length * Short.SIZE / Byte.SIZE); break; case INT_TYPE: maxCompressedSize += Snappy.maxCompressedLength(colSet.length * Integer.SIZE / Byte.SIZE); break; case BIGINT_TYPE: maxCompressedSize += Snappy.maxCompressedLength(colSet.length * Long.SIZE / Byte.SIZE); break; case DOUBLE_TYPE: maxCompressedSize += Snappy.maxCompressedLength(colSet.length * Double.SIZE / Byte.SIZE); break; case BINARY_TYPE: // Reserve space for the size of the compressed array of row sizes. maxCompressedSize += Snappy.maxCompressedLength(colSet.length * Integer.SIZE / Byte.SIZE); // Reserve space for the size of the compressed flattened bytes. for (ByteBuffer nextBuffer : colSet[colNum].toTColumn().getBinaryVal().getValues()) { maxCompressedSize += Snappy.maxCompressedLength(nextBuffer.limit()); } // Add an additional value to the list of compressed chunk sizes (length of `rowSize` array). uncompressedFooterLength++; break; case STRING_TYPE: // Reserve space for the size of the compressed array of row sizes. maxCompressedSize += Snappy.maxCompressedLength(colSet.length * Integer.SIZE / Byte.SIZE); // Reserve space for the size of the compressed flattened bytes. for (String nextString : colSet[colNum].toTColumn().getStringVal().getValues()) { maxCompressedSize += Snappy .maxCompressedLength(nextString.getBytes(StandardCharsets.UTF_8).length); } // Add an additional value to the list of compressed chunk sizes (length of `rowSize` array). uncompressedFooterLength++; break; default: throw new IllegalStateException("Unrecognized column type"); } } // Reserve space for the footer. maxCompressedSize += Snappy.maxCompressedLength(uncompressedFooterLength * Integer.SIZE / Byte.SIZE); // Allocate the output container. ByteBuffer output = ByteBuffer.allocate(maxCompressedSize); // Allocate the footer. This goes in the footer because we don't know the chunk sizes until after // the columns have been compressed and written. ArrayList<Integer> compressedSize = new ArrayList<Integer>(uncompressedFooterLength); // Write to the output buffer. try { // Write the header. compressedSize.add(writePrimitives(dataType, output)); // Write the compressed columns and metadata. for (int colNum = 0; colNum < colSet.length; colNum++) { switch (TTypeId.findByValue(dataType[colNum])) { case BOOLEAN_TYPE: { TBoolColumn column = colSet[colNum].toTColumn().getBoolVal(); List<Boolean> bools = column.getValues(); BitSet bsBools = new BitSet(bools.size()); for (int rowNum = 0; rowNum < bools.size(); rowNum++) { bsBools.set(rowNum, bools.get(rowNum)); } compressedSize.add(writePrimitives(column.getNulls(), output)); // BitSet won't write trailing zeroes so we encode the length output.putInt(column.getValuesSize()); compressedSize.add(writePrimitives(bsBools.toByteArray(), output)); break; } case TINYINT_TYPE: { TByteColumn column = colSet[colNum].toTColumn().getByteVal(); compressedSize.add(writePrimitives(column.getNulls(), output)); compressedSize.add(writeBoxedBytes(column.getValues(), output)); break; } case SMALLINT_TYPE: { TI16Column column = colSet[colNum].toTColumn().getI16Val(); compressedSize.add(writePrimitives(column.getNulls(), output)); compressedSize.add(writeBoxedShorts(column.getValues(), output)); break; } case INT_TYPE: { TI32Column column = colSet[colNum].toTColumn().getI32Val(); compressedSize.add(writePrimitives(column.getNulls(), output)); compressedSize.add(writeBoxedIntegers(column.getValues(), output)); break; } case BIGINT_TYPE: { TI64Column column = colSet[colNum].toTColumn().getI64Val(); compressedSize.add(writePrimitives(column.getNulls(), output)); compressedSize.add(writeBoxedLongs(column.getValues(), output)); break; } case DOUBLE_TYPE: { TDoubleColumn column = colSet[colNum].toTColumn().getDoubleVal(); compressedSize.add(writePrimitives(column.getNulls(), output)); compressedSize.add(writeBoxedDoubles(column.getValues(), output)); break; } case BINARY_TYPE: { TBinaryColumn column = colSet[colNum].toTColumn().getBinaryVal(); // Initialize the array of row sizes. int[] rowSizes = new int[column.getValuesSize()]; int totalSize = 0; for (int rowNum = 0; rowNum < column.getValuesSize(); rowNum++) { rowSizes[rowNum] = column.getValues().get(rowNum).limit(); totalSize += column.getValues().get(rowNum).limit(); } // Flatten the data for Snappy for a better compression ratio. ByteBuffer flattenedData = ByteBuffer.allocate(totalSize); for (int rowNum = 0; rowNum < column.getValuesSize(); rowNum++) { flattenedData.put(column.getValues().get(rowNum)); } // Write nulls bitmap. compressedSize.add(writePrimitives(column.getNulls(), output)); // Write the list of row sizes. compressedSize.add(writePrimitives(rowSizes, output)); // Write the compressed, flattened data. compressedSize.add(writePrimitives(flattenedData.array(), output)); break; } case STRING_TYPE: { TStringColumn column = colSet[colNum].toTColumn().getStringVal(); // Initialize the array of row sizes. int[] rowSizes = new int[column.getValuesSize()]; int totalSize = 0; for (int rowNum = 0; rowNum < column.getValuesSize(); rowNum++) { rowSizes[rowNum] = column.getValues().get(rowNum).length(); totalSize += column.getValues().get(rowNum).length(); } // Flatten the data for Snappy for a better compression ratio. StringBuilder flattenedData = new StringBuilder(totalSize); for (int rowNum = 0; rowNum < column.getValuesSize(); rowNum++) { flattenedData.append(column.getValues().get(rowNum)); } // Write nulls bitmap. compressedSize.add(writePrimitives(column.getNulls(), output)); // Write the list of row sizes. compressedSize.add(writePrimitives(rowSizes, output)); // Write the flattened data. compressedSize.add( writePrimitives(flattenedData.toString().getBytes(StandardCharsets.UTF_8), output)); break; } default: throw new IllegalStateException("Unrecognized column type"); } } // Write the footer. output.putInt(writeBoxedIntegers(compressedSize, output)); } catch (IOException e) { e.printStackTrace(); } output.flip(); return output; }
From source file:hivemall.topicmodel.ProbabilisticTopicModelBaseUDTF.java
protected void recordTrainSampleToTempFile(@Nonnull final String[] wordCounts) throws HiveException { if (iterations == 1) { return;//from w ww. jav a2 s . c om } ByteBuffer buf = inputBuf; NioStatefulSegment dst = fileIO; if (buf == null) { final File file; try { file = File.createTempFile("hivemall_topicmodel", ".sgmt"); file.deleteOnExit(); if (!file.canWrite()) { throw new UDFArgumentException("Cannot write a temporary file: " + file.getAbsolutePath()); } logger.info("Record training samples to a file: " + file.getAbsolutePath()); } catch (IOException ioe) { throw new UDFArgumentException(ioe); } catch (Throwable e) { throw new UDFArgumentException(e); } this.inputBuf = buf = ByteBuffer.allocateDirect(1024 * 1024); // 1 MB this.fileIO = dst = new NioStatefulSegment(file, false); } // wordCounts length, wc1 length, wc1 string, wc2 length, wc2 string, ... int wcLengthTotal = 0; for (String wc : wordCounts) { if (wc == null) { continue; } wcLengthTotal += wc.length(); } int recordBytes = SizeOf.INT + SizeOf.INT * wordCounts.length + wcLengthTotal * SizeOf.CHAR; int requiredBytes = SizeOf.INT + recordBytes; // need to allocate space for "recordBytes" itself int remain = buf.remaining(); if (remain < requiredBytes) { writeBuffer(buf, dst); } buf.putInt(recordBytes); buf.putInt(wordCounts.length); for (String wc : wordCounts) { NIOUtils.putString(wc, buf); } }
From source file:com.github.ambry.utils.UtilsTest.java
@Test public void testReadStrings() throws IOException { // good case//from ww w . j a va 2s . com ByteBuffer buffer = ByteBuffer.allocate(10); buffer.putShort((short) 8); String s = getRandomString(8); buffer.put(s.getBytes()); buffer.flip(); String outputString = Utils.readShortString(new DataInputStream(new ByteBufferInputStream(buffer))); Assert.assertEquals(s, outputString); // 0-length buffer.rewind(); buffer.putShort(0, (short) 0); outputString = Utils.readShortString(new DataInputStream(new ByteBufferInputStream(buffer))); Assert.assertTrue(outputString.isEmpty()); // failed case buffer.rewind(); buffer.putShort((short) 10); buffer.put(s.getBytes()); buffer.flip(); try { outputString = Utils.readShortString(new DataInputStream(new ByteBufferInputStream(buffer))); Assert.assertTrue(false); } catch (IllegalArgumentException e) { Assert.assertTrue(true); } buffer.rewind(); buffer.putShort(0, (short) -1); try { outputString = Utils.readShortString(new DataInputStream(new ByteBufferInputStream(buffer))); Assert.fail("Should have encountered exception with negative length."); } catch (IllegalArgumentException e) { } // good case buffer = ByteBuffer.allocate(40004); buffer.putInt(40000); s = getRandomString(40000); buffer.put(s.getBytes()); buffer.flip(); outputString = Utils.readIntString(new DataInputStream(new ByteBufferInputStream(buffer)), StandardCharsets.UTF_8); Assert.assertEquals(s, outputString); // 0-length buffer.rewind(); buffer.putInt(0, 0); outputString = Utils.readShortString(new DataInputStream(new ByteBufferInputStream(buffer))); Assert.assertTrue(outputString.isEmpty()); // failed case buffer.rewind(); buffer.putInt(50000); buffer.put(s.getBytes()); buffer.flip(); try { outputString = Utils.readIntString(new DataInputStream(new ByteBufferInputStream(buffer)), StandardCharsets.UTF_8); fail("Should have failed"); } catch (IllegalArgumentException e) { // expected. } buffer.rewind(); buffer.putInt(0, -1); try { Utils.readIntString(new DataInputStream(new ByteBufferInputStream(buffer)), StandardCharsets.UTF_8); Assert.fail("Should have encountered exception with negative length."); } catch (IllegalArgumentException e) { // expected. } }
From source file:com.github.ambry.utils.UtilsTest.java
@Test public void testDeserializeString() { String randomString = getRandomString(10); ByteBuffer outputBuffer = ByteBuffer.allocate(4 + randomString.getBytes().length); Utils.serializeString(outputBuffer, randomString, StandardCharsets.US_ASCII); outputBuffer.flip();//from ww w .j a va 2s . co m String outputString = Utils.deserializeString(outputBuffer, StandardCharsets.US_ASCII); assertEquals("Input and output strings don't match", randomString, outputString); randomString = getRandomString(10) + ""; outputBuffer = ByteBuffer.allocate(4 + randomString.getBytes().length); Utils.serializeString(outputBuffer, randomString, StandardCharsets.US_ASCII); outputBuffer.flip(); outputString = Utils.deserializeString(outputBuffer, StandardCharsets.US_ASCII); randomString = randomString.substring(0, randomString.length() - 1) + "?"; assertEquals("Input and output strings don't match", randomString, outputString); randomString = ""; outputBuffer = ByteBuffer.allocate(4); Utils.serializeString(outputBuffer, randomString, StandardCharsets.US_ASCII); outputBuffer.flip(); outputString = Utils.deserializeString(outputBuffer, StandardCharsets.US_ASCII); assertEquals("Output string \"" + outputString + "\" expected to be empty", outputString, ""); randomString = getRandomString(10); outputBuffer = ByteBuffer.allocate(4 + randomString.getBytes().length); outputBuffer.putInt(12); outputBuffer.put(randomString.getBytes()); outputBuffer.flip(); try { outputString = Utils.deserializeString(outputBuffer, StandardCharsets.US_ASCII); Assert.fail("Deserialization should have failed " + randomString); } catch (RuntimeException e) { } }
From source file:com.healthmarketscience.jackcess.Column.java
/** * Writes the column definitions into a table definition buffer. * @param buffer Buffer to write to/*from w ww . j a v a2s . c om*/ * @param columns List of Columns to write definitions for */ protected static void writeDefinitions(TableCreator creator, ByteBuffer buffer) throws IOException { List<Column> columns = creator.getColumns(); short columnNumber = (short) 0; short fixedOffset = (short) 0; short variableOffset = (short) 0; // we specifically put the "long variable" values after the normal // variable length values so that we have a better chance of fitting it // all (because "long variable" values can go in separate pages) short longVariableOffset = Column.countNonLongVariableLength(columns); for (Column col : columns) { // record this for later use when writing indexes col.setColumnNumber(columnNumber); int position = buffer.position(); buffer.put(col.getType().getValue()); buffer.putInt(Table.MAGIC_TABLE_NUMBER); //constant magic number buffer.putShort(columnNumber); //Column Number if (col.isVariableLength()) { if (!col.getType().isLongValue()) { buffer.putShort(variableOffset++); } else { buffer.putShort(longVariableOffset++); } } else { buffer.putShort((short) 0); } buffer.putShort(columnNumber); //Column Number again if (col.getType().isTextual()) { // this will write 4 bytes (note we don't support writing dbs which // use the text code page) writeSortOrder(buffer, col.getTextSortOrder(), creator.getFormat()); } else { if (col.getType().getHasScalePrecision()) { buffer.put(col.getPrecision()); // numeric precision buffer.put(col.getScale()); // numeric scale } else { buffer.put((byte) 0x00); //unused buffer.put((byte) 0x00); //unused } buffer.putShort((short) 0); //Unknown } buffer.put(col.getColumnBitFlags()); // misc col flags if (col.isCompressedUnicode()) { //Compressed buffer.put((byte) 1); } else { buffer.put((byte) 0); } buffer.putInt(0); //Unknown, but always 0. //Offset for fixed length columns if (col.isVariableLength()) { buffer.putShort((short) 0); } else { buffer.putShort(fixedOffset); fixedOffset += col.getType().getFixedSize(col.getLength()); } if (!col.getType().isLongValue()) { buffer.putShort(col.getLength()); //Column length } else { buffer.putShort((short) 0x0000); // unused } columnNumber++; if (LOG.isDebugEnabled()) { LOG.debug("Creating new column def block\n" + ByteUtil.toHexString(buffer, position, creator.getFormat().SIZE_COLUMN_DEF_BLOCK)); } } for (Column col : columns) { Table.writeName(buffer, col.getName(), creator.getCharset()); } }
From source file:org.apache.hadoop.hbase.io.hfile.HFileBlock.java
/** * Adds metadata at current position (position is moved forward). Does not flip or reset. * @return The passed <code>destination</code> with metadata added. *///from ww w.jav a 2s . c o m private ByteBuffer addMetaData(final ByteBuffer destination) { destination.put(this.fileContext.isUseHBaseChecksum() ? (byte) 1 : (byte) 0); destination.putLong(this.offset); destination.putInt(this.nextBlockOnDiskSize); return destination; }
From source file:com.github.ambry.commons.BlobIdTest.java
/** * Build a string that resembles a bad blobId. * @param version The version number to be embedded in the blobId. * @param type The {@link BlobIdType} of the blobId. * @param datacenterId The datacenter id to be embedded in the blobId. * @param accountId The account id to be embedded in the blobId. * @param containerId The container id to be embedded in the blobId. * @param partitionId The partition id to be embedded in the blobId. * @param uuidLength The length of the uuid. * @param uuid The UUID to be embedded in the blobId. * @param extraChars Extra characters to put at the end of the ID. * @return a base-64 encoded {@link String} representing the blobId. *///from w w w. j av a 2s. c o m private String buildBadBlobId(short version, BlobIdType type, Byte datacenterId, Short accountId, Short containerId, PartitionId partitionId, int uuidLength, String uuid, String extraChars) { int idLength; ByteBuffer idBuf; switch (version) { case BLOB_ID_V1: idLength = 2 + partitionId.getBytes().length + 4 + uuid.length() + extraChars.length(); idBuf = ByteBuffer.allocate(idLength); idBuf.putShort(version); break; case BLOB_ID_V2: idLength = 2 + 1 + 1 + 2 + 2 + partitionId.getBytes().length + 4 + uuid.length() + extraChars.length(); idBuf = ByteBuffer.allocate(idLength); idBuf.putShort(version); idBuf.put((byte) 0); idBuf.put(datacenterId); idBuf.putShort(accountId); idBuf.putShort(containerId); break; case BLOB_ID_V3: case BLOB_ID_V4: case BLOB_ID_V5: case BLOB_ID_V6: idLength = 2 + 1 + 1 + 2 + 2 + partitionId.getBytes().length + 4 + uuid.length() + extraChars.length(); idBuf = ByteBuffer.allocate(idLength); idBuf.putShort(version); idBuf.put((byte) type.ordinal()); idBuf.put(datacenterId); idBuf.putShort(accountId); idBuf.putShort(containerId); break; default: idLength = 2 + partitionId.getBytes().length + 4 + uuid.length() + extraChars.length(); idBuf = ByteBuffer.allocate(idLength); idBuf.putShort(version); break; } idBuf.put(partitionId.getBytes()); switch (version) { case BLOB_ID_V6: UUID uuidObj = UUID.fromString(uuid); idBuf.putLong(uuidObj.getMostSignificantBits()); idBuf.putLong(uuidObj.getLeastSignificantBits()); break; default: idBuf.putInt(uuidLength); idBuf.put(uuid.getBytes()); } idBuf.put(extraChars.getBytes()); return Base64.encodeBase64URLSafeString(idBuf.array()); }
From source file:com.healthmarketscience.jackcess.impl.ColumnImpl.java
protected ByteBuffer writeFixedLengthField(Object obj, ByteBuffer buffer) throws IOException { // since booleans are not written by this method, it's safe to convert any // incoming boolean into an integer. obj = booleanToInteger(obj);//from www . j a va 2s .c o m switch (getType()) { case BOOLEAN: //Do nothing break; case BYTE: buffer.put(toNumber(obj).byteValue()); break; case INT: buffer.putShort(toNumber(obj).shortValue()); break; case LONG: buffer.putInt(toNumber(obj).intValue()); break; case MONEY: writeCurrencyValue(buffer, obj); break; case FLOAT: buffer.putFloat(toNumber(obj).floatValue()); break; case DOUBLE: buffer.putDouble(toNumber(obj).doubleValue()); break; case SHORT_DATE_TIME: writeDateValue(buffer, obj); break; case TEXT: // apparently text numeric values are also occasionally written as fixed // length... int numChars = getLengthInUnits(); // force uncompressed encoding for fixed length text buffer.put(encodeTextValue(obj, numChars, numChars, true)); break; case GUID: writeGUIDValue(buffer, obj); break; case NUMERIC: // yes, that's right, occasionally numeric values are written as fixed // length... writeNumericValue(buffer, obj); break; case BINARY: case UNKNOWN_0D: case UNKNOWN_11: case COMPLEX_TYPE: buffer.putInt(toNumber(obj).intValue()); break; case UNSUPPORTED_FIXEDLEN: byte[] bytes = toByteArray(obj); if (bytes.length != getLength()) { throw new IOException( "Invalid fixed size binary data, size " + getLength() + ", got " + bytes.length); } buffer.put(bytes); break; default: throw new IOException("Unsupported data type: " + getType()); } return buffer; }
From source file:au.org.ala.layers.intersect.Grid.java
/** * for DomainGenerator//from ww w . j a v a 2s . com * <p/> * writes out a list of double (same as getGrid() returns) to a file * <p/> * byteorderlsb * data type, FLOAT * * @param newfilename * @param dfiltered */ public void writeGrid(String newfilename, int[] dfiltered, double xmin, double ymin, double xmax, double ymax, double xres, double yres, int nrows, int ncols) { int size, i, length = dfiltered.length; double maxvalue = Integer.MAX_VALUE * -1; double minvalue = Integer.MAX_VALUE; //write data as whole file RandomAccessFile afile = null; try { //read of random access file can throw an exception afile = new RandomAccessFile(newfilename + ".gri", "rw"); size = 4; byte[] b = new byte[size * length]; ByteBuffer bb = ByteBuffer.wrap(b); if (byteorderLSB) { bb.order(ByteOrder.LITTLE_ENDIAN); } else { bb.order(ByteOrder.BIG_ENDIAN); } for (i = 0; i < length; i++) { bb.putInt(dfiltered[i]); } afile.write(b); } catch (Exception e) { logger.error("error writing grid file", e); } finally { if (afile != null) { try { afile.close(); } catch (Exception e) { logger.error(e.getMessage(), e); } } } writeHeader(newfilename, xmin, ymin, xmin + xres * ncols, ymin + yres * nrows, xres, yres, nrows, ncols, minvalue, maxvalue, "INT4BYTES", "-9999"); }
From source file:com.healthmarketscience.jackcess.Column.java
/** * Write an LVAL column into a ByteBuffer inline if it fits, otherwise in * other data page(s).//from w w w . j a va2s .com * @param value Value of the LVAL column * @return A buffer containing the LVAL definition and (possibly) the column * value (unless written to other pages) * @usage _advanced_method_ */ public ByteBuffer writeLongValue(byte[] value, int remainingRowLength) throws IOException { if (value.length > getType().getMaxSize()) { throw new IOException( "value too big for column, max " + getType().getMaxSize() + ", got " + value.length); } // determine which type to write byte type = 0; int lvalDefLen = getFormat().SIZE_LONG_VALUE_DEF; if (((getFormat().SIZE_LONG_VALUE_DEF + value.length) <= remainingRowLength) && (value.length <= getFormat().MAX_INLINE_LONG_VALUE_SIZE)) { type = LONG_VALUE_TYPE_THIS_PAGE; lvalDefLen += value.length; } else if (value.length <= getFormat().MAX_LONG_VALUE_ROW_SIZE) { type = LONG_VALUE_TYPE_OTHER_PAGE; } else { type = LONG_VALUE_TYPE_OTHER_PAGES; } ByteBuffer def = getPageChannel().createBuffer(lvalDefLen); // take length and apply type to first byte int lengthWithFlags = value.length | (type << 24); def.putInt(lengthWithFlags); if (type == LONG_VALUE_TYPE_THIS_PAGE) { // write long value inline def.putInt(0); def.putInt(0); //Unknown def.put(value); } else { TempPageHolder lvalBufferH = getTable().getLongValueBuffer(); ByteBuffer lvalPage = null; int firstLvalPageNum = PageChannel.INVALID_PAGE_NUMBER; byte firstLvalRow = 0; // write other page(s) switch (type) { case LONG_VALUE_TYPE_OTHER_PAGE: lvalPage = getLongValuePage(value.length, lvalBufferH); firstLvalPageNum = lvalBufferH.getPageNumber(); firstLvalRow = (byte) Table.addDataPageRow(lvalPage, value.length, getFormat(), 0); lvalPage.put(value); getPageChannel().writePage(lvalPage, firstLvalPageNum); break; case LONG_VALUE_TYPE_OTHER_PAGES: ByteBuffer buffer = ByteBuffer.wrap(value); int remainingLen = buffer.remaining(); buffer.limit(0); lvalPage = getLongValuePage(getFormat().MAX_LONG_VALUE_ROW_SIZE, lvalBufferH); firstLvalPageNum = lvalBufferH.getPageNumber(); int lvalPageNum = firstLvalPageNum; ByteBuffer nextLvalPage = null; int nextLvalPageNum = 0; while (remainingLen > 0) { lvalPage.clear(); // figure out how much we will put in this page (we need 4 bytes for // the next page pointer) int chunkLength = Math.min(getFormat().MAX_LONG_VALUE_ROW_SIZE - 4, remainingLen); // figure out if we will need another page, and if so, allocate it if (chunkLength < remainingLen) { // force a new page to be allocated lvalBufferH.clear(); nextLvalPage = getLongValuePage(getFormat().MAX_LONG_VALUE_ROW_SIZE, lvalBufferH); nextLvalPageNum = lvalBufferH.getPageNumber(); } else { nextLvalPage = null; nextLvalPageNum = 0; } // add row to this page byte lvalRow = (byte) Table.addDataPageRow(lvalPage, chunkLength + 4, getFormat(), 0); // write next page info (we'll always be writing into row 0 for // newly created pages) lvalPage.put((byte) 0); // row number ByteUtil.put3ByteInt(lvalPage, nextLvalPageNum); // page number // write this page's chunk of data buffer.limit(buffer.limit() + chunkLength); lvalPage.put(buffer); remainingLen -= chunkLength; // write new page to database getPageChannel().writePage(lvalPage, lvalPageNum); if (lvalPageNum == firstLvalPageNum) { // save initial row info firstLvalRow = lvalRow; } else { // check assertion that we wrote to row 0 for all subsequent pages if (lvalRow != (byte) 0) { throw new IllegalStateException("Expected row 0, but was " + lvalRow); } } // move to next page lvalPage = nextLvalPage; lvalPageNum = nextLvalPageNum; } break; default: throw new IOException("Unrecognized long value type: " + type); } // update def def.put(firstLvalRow); ByteUtil.put3ByteInt(def, firstLvalPageNum); def.putInt(0); //Unknown } def.flip(); return def; }