Github user JamesRTaylor commented on a diff in the pull request:

    https://github.com/apache/incubator-phoenix/pull/8#discussion_r9974795
  
    --- Diff: 
phoenix-core/src/main/java/org/apache/phoenix/schema/PArrayDataType.java ---
    @@ -228,49 +365,121 @@ public Object toObject(Object object, PDataType 
actualType, SortOrder sortOrder)
         * @param noOfElements
         * @param byteSize
         * @param capacity 
    +    * @param trailingNulls 
         * @return
         */
        private byte[] bytesFromByteBuffer(PhoenixArray array, ByteBuffer 
buffer,
                        int noOfElements, PDataType baseType, int capacity) {
    -           int temp = noOfElements;
             if (buffer == null) return null;
    -        buffer.put(ARRAY_SERIALIZATION_VERSION);
    -        buffer.putInt(noOfElements);
             if (!baseType.isFixedWidth() || 
baseType.isCoercibleTo(PDataType.VARCHAR)) {
    -            int fillerForOffsetByteArray = buffer.position();
    -            buffer.position(fillerForOffsetByteArray + Bytes.SIZEOF_INT);
    +            int tempNoOfElements = noOfElements;
                 ByteBuffer offsetArray = ByteBuffer.allocate(capacity);
    -            if(noOfElements < 0){
    -                   noOfElements = -noOfElements;
    +            if(tempNoOfElements < 0){
    +                tempNoOfElements = -tempNoOfElements;
                 }
    -            for (int i = 0; i < noOfElements; i++) {
    -                // Not fixed width
    -                           if (temp < 0) {
    -                                   offsetArray.putInt(buffer.position());
    -                           } else {
    -                                   
offsetArray.putShort((short)(buffer.position() - Short.MAX_VALUE));
    -                           }
    +            int nulls = 0;
    +            int nullCount = 0;
    +            for (int i = 0; i < tempNoOfElements; i++) {
                     byte[] bytes = array.toBytes(i);
    -                buffer.put(bytes);
    +                markOffset(buffer, noOfElements, offsetArray);
    +                if(bytes.length == 0){
    +                   nulls++;
    +                   nullCount++;
    +                } else {
    +                    nulls = serializeNullsIntoBuffer(buffer, nulls);
    +                    buffer.put(bytes);
    +                    buffer.put(QueryConstants.SEPARATOR_BYTE);
    +                }
                 }
    +            buffer.put(QueryConstants.SEPARATOR_BYTE);
    +            buffer.put(QueryConstants.SEPARATOR_BYTE);
                 int offsetArrayPosition = buffer.position();
                 buffer.put(offsetArray.array());
    -            buffer.position(fillerForOffsetByteArray);
                 buffer.putInt(offsetArrayPosition);
    +            buffer.putInt(tempNoOfElements - nullCount);
             } else {
                 for (int i = 0; i < noOfElements; i++) {
                     byte[] bytes = array.toBytes(i);
                     buffer.put(bytes);
                 }
             }
    +        serializeHeaderInfoIntoBuffer(buffer, noOfElements);
             return buffer.array();
        }
     
    -   private static int initOffsetArray(int noOfElements, int baseSize) {
    +    private void markOffset(ByteBuffer buffer, int noOfElements, 
ByteBuffer offsetArray) {
    +        if (noOfElements < 0) {
    +            offsetArray.putInt(buffer.position());
    +        } else {
    +            offsetArray.putShort((short)(buffer.position() - 
Short.MAX_VALUE));
    +        }
    +    }
    +
    +    public static int serailizeOffsetArrayIntoStream(DataOutputStream 
oStream, TrustedByteArrayOutputStream byteStream,
    +            int noOfElements, int elementLength, int[] offsetPos) throws 
IOException {
    +        int offsetPosition = (byteStream.size());
    +        byte[] offsetArr = null;
    +        int incr = 0;
    +        boolean useInt = true;
    +        if (PArrayDataType.useShortForOffsetArray(elementLength)) {
    +            offsetArr = new 
byte[PArrayDataType.initOffsetArray(noOfElements, Bytes.SIZEOF_SHORT)];
    +            incr = Bytes.SIZEOF_SHORT;
    +            useInt = false;
    +        } else {
    +            offsetArr = new 
byte[PArrayDataType.initOffsetArray(noOfElements, Bytes.SIZEOF_INT)];
    +            incr = Bytes.SIZEOF_INT;
    +            noOfElements = -noOfElements;
    +        }
    +        int off = 0;
    +        off = fillOffsetArr(offsetPos, offsetArr, incr, off, useInt);
    +        oStream.write(offsetArr);
    +        oStream.writeInt(offsetPosition);
    +        return noOfElements;
    +    }
    +
    +    private static int fillOffsetArr(int[] offsetPos, byte[] offsetArr, 
int incr, int off, boolean useInt) {
    +        for (int pos : offsetPos) {
    --- End diff --
    
    Not really worth having a function for this. Just have two for loops in the 
above if statement instead. Then you don't need to check the useInt for each 
element.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. To do so, please top-post your response.
If your project does not have this feature enabled and wishes so, or if the
feature is enabled but not working, please contact infrastructure at
[email protected] or file a JIRA ticket with INFRA.
---

Reply via email to