@Override public CalendarInterval getInterval(int ordinal) { assertIndexIsValid(ordinal); final int offset = getElementOffset(ordinal); if (offset < 0) return null; final int months = (int) PlatformDependent.UNSAFE.getLong(baseObject, baseOffset + offset); final long microseconds = PlatformDependent.UNSAFE.getLong(baseObject, baseOffset + offset + 8); return new CalendarInterval(months, microseconds); }
@Override public double getDouble(int ordinal) { assertIndexIsValid(ordinal); final int offset = getElementOffset(ordinal); if (offset < 0) return 0; return PlatformDependent.UNSAFE.getDouble(baseObject, baseOffset + offset); }
@Override public boolean getBoolean(int ordinal) { assertIndexIsValid(ordinal); final int offset = getElementOffset(ordinal); if (offset < 0) return false; return PlatformDependent.UNSAFE.getBoolean(baseObject, baseOffset + offset); }
@Override public Decimal getDecimal(int ordinal, int precision, int scale) { assertIndexIsValid(ordinal); final int offset = getElementOffset(ordinal); if (offset < 0) return null; if (precision <= Decimal.MAX_LONG_DIGITS()) { final long value = PlatformDependent.UNSAFE.getLong(baseObject, baseOffset + offset); return Decimal.apply(value, precision, scale); } else { final byte[] bytes = getBinary(ordinal); final BigInteger bigInteger = new BigInteger(bytes); final BigDecimal javaDecimal = new BigDecimal(bigInteger, scale); return Decimal.apply(new scala.math.BigDecimal(javaDecimal), precision, scale); } }
/** Write a record to the sorter. */ public void insertRecord( Object recordBaseObject, long recordBaseOffset, int lengthInBytes, long prefix) throws IOException { // Need 4 bytes to store the record length. final int totalSpaceRequired = lengthInBytes + 4; if (!haveSpaceForRecord(totalSpaceRequired)) { allocateSpaceForRecord(totalSpaceRequired); } final long recordAddress = memoryManager.encodePageNumberAndOffset(currentPage, currentPagePosition); final Object dataPageBaseObject = currentPage.getBaseObject(); PlatformDependent.UNSAFE.putInt(dataPageBaseObject, currentPagePosition, lengthInBytes); currentPagePosition += 4; PlatformDependent.copyMemory( recordBaseObject, recordBaseOffset, dataPageBaseObject, currentPagePosition, lengthInBytes); currentPagePosition += lengthInBytes; freeSpaceInCurrentPage -= totalSpaceRequired; sorter.insertRecord(recordAddress, prefix); }
/** Returns a 64-bit integer that can be used as the prefix used in sorting. */ public long getPrefix() { // Since JVMs are either 4-byte aligned or 8-byte aligned, we check the size of the string. // If size is 0, just return 0. // If size is between 0 and 4 (inclusive), assume data is 4-byte aligned under the hood and // use a getInt to fetch the prefix. // If size is greater than 4, assume we have at least 8 bytes of data to fetch. // After getting the data, we use a mask to mask out data that is not part of the string. long p; long mask = 0; if (byteOrder == ByteOrder.LITTLE_ENDIAN) { if (numBytes >= 8) { p = PlatformDependent.UNSAFE.getLong(base, offset); } else if (numBytes > 4) { p = PlatformDependent.UNSAFE.getLong(base, offset); mask = (1L << (8 - numBytes) * 8) - 1; } else if (numBytes > 0) { p = (long) PlatformDependent.UNSAFE.getInt(base, offset); mask = (1L << (8 - numBytes) * 8) - 1; } else { p = 0; } p = java.lang.Long.reverseBytes(p); } else { // byteOrder == ByteOrder.BIG_ENDIAN if (numBytes >= 8) { p = PlatformDependent.UNSAFE.getLong(base, offset); } else if (numBytes > 4) { p = PlatformDependent.UNSAFE.getLong(base, offset); mask = (1L << (8 - numBytes) * 8) - 1; } else if (numBytes > 0) { p = ((long) PlatformDependent.UNSAFE.getInt(base, offset)) << 32; mask = (1L << (8 - numBytes) * 8) - 1; } else { p = 0; } } p &= ~mask; return p; }
private int getElementOffset(int ordinal) { return PlatformDependent.UNSAFE.getInt(baseObject, baseOffset + ordinal * 4L); }